nginx开发_配置项
nginx开发笔记_配置项
模块的配置项即nginx.conf中的指令,HTTP模块指令可以分为三个级别:
- main级,直接写在http{}块中的指令
- server级,写在server{}块中的指令
- location级,写在location{}块中的指令
配置项定义模板
在自定义模块中使用配置项,需要配置ngx_module_t的commands属性以及ctx属性,并需要定义一个结构体用于存放配置信息。
常用的模板如下:
/* 存放配置信息的自定义结构体 */
typedef struct
{
ngx_flag_t my_flag;
} ngx_http_mytest_conf_t;
/* 模块声明 */
ngx_module_t ngx_http_mytest_module =
{
NGX_MODULE_V1,
&ngx_http_mytest_module_ctx, /* module context */
ngx_http_mytest_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};
/* 配置项处理回调函数注册 */
static ngx_http_module_t ngx_http_mytest_module_ctx =
{
ngx_http_mytest_pre_conf, /* preconfiguration */
ngx_http_mytest_post_conf, /* postconfiguration */
ngx_http_mytest_create_main_conf, /* create main configuration */
ngx_http_mytest_init_main_conf, /* init main configuration */
ngx_http_mytest_create_srv_conf, /* create server configuration */
ngx_http_mytest_merge_srv_conf, /* merge server configuration */
ngx_http_mytest_create_loc_conf, /* create location configuration */
ngx_http_mytest_merge_loc_conf /* merge location configuration */
};
/* 自定义的配置项 */
static ngx_command_t ngx_http_mytest_commands[] =
{
{
ngx_string("test_flag"),
NGX_HTTP_LOC_CONF | NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_mytest_conf_t, my_flag),
NULL
},
ngx_null_command
};
配置项信息
配置项信息通过ngx_command_t类型指定
struct ngx_command_s {
ngx_str_t name;
ngx_uint_t type;
char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
ngx_uint_t conf;
ngx_uint_t offset;
void *post;
};
name 命令名称
type 设置配置项允许在哪些配置块中使用、配置项携带的参数个数、参数形式信息。具体可以参考ngx_conf_file.h和<深入理解Nginx 第2版>P116 表4-1。常用选项如下
/*
* AAAA number of arguments
* FF command flags
* TT command type, i.e. HTTP "location" or "server" command
*/
#define NGX_HTTP_MAIN_CONF 0x02000000
#define NGX_HTTP_SRV_CONF 0x04000000
#define NGX_HTTP_LOC_CONF 0x08000000
#define NGX_CONF_BLOCK 0x00000100
#define NGX_CONF_FLAG 0x00000200
#define NGX_CONF_ANY 0x00000400
#define NGX_CONF_1MORE 0x00000800
#define NGX_CONF_2MORE 0x00001000
#define NGX_CONF_NOARGS 0x00000001
#define NGX_CONF_TAKE1 0x00000002
#define NGX_CONF_TAKE2 0x00000004
#define NGX_CONF_TAKE3 0x00000008
#define NGX_CONF_TAKE4 0x00000010
- set属性指定配置项解析函数,ngx提供了12个常用的解析函数如下所示,解析的格式可以参考<深入理解Nginx 第2版>P118 表4-2 。也可以实现自定义的解析函数。
char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_str_array_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_keyval_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_off_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_enum_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
conf 用于指定配置项的偏移,与后文的create_xxx_conf回调函数有关。例如配置项是通过create_loc_conf函数创建的,此处的配置就应该为NGX_HTTP_LOC_CONF_OFFSET。
可选参数如下:
#define NGX_HTTP_MAIN_CONF_OFFSET offsetof(ngx_http_conf_ctx_t, main_conf)
#define NGX_HTTP_SRV_CONF_OFFSET offsetof(ngx_http_conf_ctx_t, srv_conf)
#define NGX_HTTP_LOC_CONF_OFFSET offsetof(ngx_http_conf_ctx_t, loc_conf)
- offset 用于指定配置项关联的结构体字段的偏移,一般使用offsetof宏设置。
- post指针,传递给set函数的参数,具体含义根据set函数而定。
配置项创建与合并
配置项创建与合并主要通过ngx_http_module_t的回调函数实现。
typedef struct {
ngx_int_t (*preconfiguration)(ngx_conf_t *cf);
ngx_int_t (*postconfiguration)(ngx_conf_t *cf);
void *(*create_main_conf)(ngx_conf_t *cf);
char *(*init_main_conf)(ngx_conf_t *cf, void *conf);
void *(*create_srv_conf)(ngx_conf_t *cf);
char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);
void *(*create_loc_conf)(ngx_conf_t *cf);
char *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);
} ngx_http_module_t;
其中preconfiguration与postconfiguration相对好理解,在配置项创建整体前后分别回调。
create_main_conf、create_srv_conf、create_loc_conf三个函数的回调次数与nginx中具体的配置有关。以如下配置为例:
http {
test_str SUPERMAN;
server {
server_name HOST1;
location /HOST1_loc1 {
test_str loc1_BANANA;
}
location /HOST1_loc2 {
}
}
server {
server_name HOST2;
test_str CAR;
location /index {
test_str FOCUS;
}
location /test {
test_str PLANE;
}
location = /50x.html {
}
}
}
HTTP模块遇到http{}配置块时将调用create_main_conf、create_srv_conf、create_loc_conf三个函数,遇到server{}块时将调用create_srv_conf、create_loc_con两个函数、遇到location{}块时将调用create_loc_con函数。所以以上配置create_main_conf将被调用1次,create_srv_conf被调用3次,create_loc_conf被调用8次。一般HTTP模块都仅使用loc级的配置。
create_xxx_conf函数中一般的内容为创建自定义配置结构体,并设置初始值。常见如下:
static void *
ngx_http_sub_create_conf(ngx_conf_t *cf)
{
ngx_http_sub_loc_conf_t *slcf;
slcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_sub_loc_conf_t));
if (slcf == NULL) {
return NULL;
}
slcf->once = NGX_CONF_UNSET;
slcf->last_modified = NGX_CONF_UNSET;
return slcf;
}
上文中提到在http{}和server{}中都会调用create_loc_conf,那么在具体处理请求时将使用那个级别的的配置,则由init_main_conf、merge_srv_conf、merge_loc_conf回调函数决定。已merge_loc_conf为例
(merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);
prev指针为父级配置的结构体,conf为子级配置的结构体。一个常用的思路时:如果子级没有配置则复用父级的,常用方式如下:
static char *
ngx_http_mytest_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
{
ngx_http_mytest_conf_t *prev = (ngx_http_mytest_conf_t *)parent;
ngx_http_mytest_conf_t *conf = (ngx_http_mytest_conf_t *)child;
ngx_conf_merge_str_value(conf->my_str, prev->my_str, "defaultstr");
return NGX_CONF_OK;
}
ngx_conf_merge_str_value是合并str类型的宏,其他宏还包括
#define ngx_conf_merge_value(conf, prev, default)
#define ngx_conf_merge_ptr_value(conf, prev, default)
#define ngx_conf_merge_uint_value(conf, prev, default)
#define ngx_conf_merge_msec_value(conf, prev, default)
#define ngx_conf_merge_sec_value(conf, prev, default)
#define ngx_conf_merge_size_value(conf, prev, default)
#define ngx_conf_merge_off_value(conf, prev, default)
#define ngx_conf_merge_str_value(conf, prev, default)
#define ngx_conf_merge_bufs_value(conf, prev, default_num, default_size)
#define ngx_conf_merge_bitmask_value(conf, prev, default)
注意merge_loc_conf与create_loc_conf类似,在三个级别中会被调用多次,以上文的配置示例来说,merge_loc_conf会被调用7次,比create_loc_conf少1次,因为http{}不需要merge。
【此处的设计逻辑个人还没想理解十分明白,初步理解分三层配置用于一个模块中http{}srv{}loc{}需要定义使用不同conf_t结构体的场景,反复调用create函数是为了实现可以选择是否复用(merge)父级的功能。】
配置项获取
一般可以通过ngx_http_request_t *r变量或者ngx_conf_t *cf变量获取配置项的内容。常用的接口如下
#define ngx_http_get_module_main_conf(r, module)
#define ngx_http_get_module_srv_conf(r, module)
#define ngx_http_get_module_loc_conf(r, module)
#define ngx_http_conf_get_module_main_conf(cf, module)
#define ngx_http_conf_get_module_srv_conf(cf, module)
#define ngx_http_conf_get_module_loc_conf(cf, module)
示例代码如下:
static ngx_int_t
ngx_http_addition_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
...
ngx_http_addition_conf_t *conf;
...
conf = ngx_http_get_module_loc_conf(r, ngx_http_addition_filter_module);
}
nginx开发_配置项的更多相关文章
- nginx开发_字符串操作函数
由于ngx_str_t为非NULL结尾的函数,且网络请求中有大量忽略大小写的需求,所以nginx内部封装了许多字符串操作相关的函数,函数名称极其相识,且使用时有有些约定,特此整理. 赋值&拷贝 ...
- nginx开发_调试日志
接口列表 核心文件ngx_log.h 主要接口如下: ngx_log_error(level, log, err, fmt, ...) ngx_log_debug(level, log, err, f ...
- Nginx开发HTTP模块入门
Nginx开发HTTP模块入门 我们以一个最简单的Hello World模块为例,学习Nginx的模块编写.假设我们的模块在nginx配置文件中的指令名称为hello_world,那我们就可以在ngi ...
- nginx开发_ngx_http_script源码解析
功能简介 nginx中有很多配置项支持以变量的形式存在,在运行时根据实时值进行处理.例如如下配置: location / { sub_filter '<a href="http://1 ...
- python开发_++i,i += 1的区分
python开发_++i,i += 1的区分 在很多编程语言(C/C++,Java等)中我们都会碰到这样的语法: 1 int i = 0; 2 ++ i; // -- i; 这样的语法在上述编程语言中 ...
- java开发_模仿百度文库_OpenOffice2PDF_注意事项
在模仿百度文库的操作过程中,有很多朋友反映出来的一些问题,是我想起了写这篇blog. 主要是让大家在做的过程中注意一些东西,否则达不到想要的效果. 第一步:我们先从 java开发_模仿百度文库_Ope ...
- Nginx开发从入门到精通 学习目录分享学习 (阿里著作)
Nginx开发从入门到精通 缘起 nginx由于出色的性能,在世界范围内受到了越来越多人的关注,在淘宝内部它更是被广泛的使用,众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部 ...
- 安卓开发_深入学习ViewPager控件
一.概述 ViewPager是android扩展包v4包(android.support.v4.view.ViewPager)中的类,这个类可以让用户左右切换当前的view. ViewPager特点: ...
- 安卓开发_浅谈ListView(SimpleAdapter数组适配器)
安卓开发_浅谈ListView(ArrayAdapter数组适配器) 学习使用ListView组件和SimapleAdapter适配器实现一个带图标的ListView列表 总共3部分 一.MainAc ...
随机推荐
- css3 画半圆和1/4圆
半圆: #circle1 { width: 100px; height: 200px; background-color: #a72525; -webkit-border-radius: 100px ...
- How to Upgrade PIP in Windows
https://datatofish.com/upgrade-pip/ 这个网站写的非常的全
- phpQuery用法总结
项目下载地址:http://code.google.com/p/phpquery/ 获取内容的方法: 第一种:newDocumentFile phpQuery::newDocumentFile($ur ...
- python type
基于2.7 版本 type 是内置函数,有两种用法 class type(object) With one argument, return the type of an object. The re ...
- Go语言并发之美
简介 多核处理器越来越普及,那有没有一种简单的办法,能够让我们写的软件释放多核的威力?答案是:Yes.随着Golang, Erlang, Scale等为并发设计的程序语言的兴起,新 ...
- 【嵌入式Linux+ARM】GPIO操作
1.GPIO介绍 GPIO(general purpose i/o ports)意思为通用输入/输出端口,通俗的说就是一些引脚. 我们可以通过它们输出高低电平 或 读入引脚的状态. s3c2440中有 ...
- react 创建组件 (四)Stateless Functional Component
上面我们提到的创建组件的方式,都是用来创建包含状态和用户交互的复杂组件,当组件本身只是用来展示,所有数据都是通过props传入的时候,我们便可以使用Stateless Functional Compo ...
- dvm进程,linux进程,应用程序进程是否同一概念
Android 运行环境主要指的虚拟机技术——Dalvik.Android中的所有Java程序都是运行在Dalvik VM上的.Android上的每个程序都有自己的线程,DVM只执行.dex的Dalv ...
- MongoDB与MySQL的插入性能测试【转】
1.1 MongoDB的简单介绍 在当今的数据库市场上,MySQL无疑是占有一席之地的.作为一个开源的关系型数据库,MySQL被大量应用在各大网站后台中,承担着信息存储的重要作用.2009年,甲骨文 ...
- 【转载】Http协议与TCP协议简单理解
在C#编写代码,很多时候会遇到Http协议或者TCP协议,这里做一个简单的理解.TCP协议对应于传输层,而HTTP协议对应于应用层,从本质上来说,二者没有可比性.Http协议是建立在TCP协议基础之上 ...