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和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个常用的解析函数如下所示,解析的格式可以参考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); }
来源:https://www.cnblogs.com/atskyline/p/7853153.html