Nginx 模块的基本结构( 三 )


post: 该字段存储一个指针 。可以指向任何一个在读取配置过程中需要的数据,以便于进行配置读取的处理 。大多数时候,都不需要,所以简单地设为 0 即可 。
看到这里,应该就比较清楚了 。ngx_http_hello_commands 这个数组每 5 个元素为一组,用来描述一个配置项的所有情况 。那么如果有多个配置项,只要按照需要再增加 5 个对应的元素对新的配置项进行说明 。
需要注意的是,就是在ngx_http_hello_commands这个数组定义的最后,都要加一个ngx_null_command作为结尾 。
模块上下文结构
这是一个 ngx_http_module_t 类型的静态变量 。这个变量实际上是提供一组回调函数指针,这些函数有在创建存储配置信息的对象的函数,也有在创建前和创建后会调用的函数 。这些函数都将被 Nginx 在合适的时间进行调用 。
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: 调用该函数创建本模块位于 http block 的配置信息存储结构 。该函数成功的时候,返回创建的配置对象 。失败的话,返回 NULL 。
  • init_main_conf: 调用该函数初始化本模块位于 http block 的配置信息存储结构 。该函数成功的时候,返回 NGX_CONF_OK 。失败的话,返回 NGX_CONF_ERROR 或错误字符串 。
  • create_srv_conf: 调用该函数创建本模块位于 http server block 的配置信息存储结构,每个 server block 会创建一个 。该函数成功的时候,返回创建的配置对象 。失败的话,返回 NULL 。
  • merge_srv_conf: 因为有些配置指令既可以出现在 http block,也可以出现在 http server block 中 。那么遇到这种情况,每个 server 都会有自己存储结构来存储该 server 的配置,但是在这种情况下 http block 中的配置与 server block 中的配置信息发生冲突的时候,就需要调用此函数进行合并,该函数并非必须提供,当预计到绝对不会发生需要合并的情况的时候,就无需提供 。当然为了安全起见还是建议提供 。该函数执行成功的时候,返回 NGX_CONF_OK 。失败的话,返回 NGX_CONF_ERROR 或错误字符串 。
  • create_loc_conf: 调用该函数创建本模块位于 location block 的配置信息存储结构 。每个在配置中指明的 location 创建一个 。该函数执行成功,返回创建的配置对象 。失败的话,返回 NULL 。
  • merge_loc_conf: 与 merge_srv_conf 类似,这个也是进行配置值合并的地方 。该函数成功的时候,返回 NGX_CONF_OK 。失败的话,返回 NGX_CONF_ERROR 或错误字符串 。
Nginx 里面的配置信息都是上下一层层的嵌套的,对于具体某个 location 的话,对于同一个配置,如果当前层次没有定义,那么就使用上层的配置,否则使用当前层次的配置 。
这些配置信息一般默认都应该设为一个未初始化的值,针对这个需求,Nginx 定义了一系列的宏定义来代表各种配置所对应数据类型的未初始化值,如下:
【Nginx 模块的基本结构】 #define NGX_CONF_UNSET -1 #define NGX_CONF_UNSET_UINT (ngx_uint_t) -1 #define NGX_CONF_UNSET_PTR (void *) -1 #define NGX_CONF_UNSET_SIZE (size_t) -1 #define NGX_CONF_UNSET_MSEC (ngx_msec_t) -1又因为对于配置项的合并,逻辑都类似,也就是前面已经说过的,如果在本层次已经配置了,也就是配置项的值已经被读取进来了(那么这些配置项的值就不会等于上面已经定义的那些 UNSET 的值),就使用本层次的值作为定义合并的结果,否则,使用上层的值,如果上层的值也是这些UNSET类的值,那就赋值为默认值,否则就使用上层的值作为合并的结果 。对于这样类似的操作,Nginx 定义了一些宏操作来做这些事情,我们来看其中一个的定义 。
#define ngx_conf_merge_uint_value(conf, prev, default)if (conf == NGX_CONF_UNSET_UINT) {conf = (prev == NGX_CONF_UNSET_UINT) ? default : prev;}显而易见,这个逻辑确实比较简单,所以其它的宏定义也类似,我们就列具其中的一部分吧 。
ngx_conf_merge_value ngx_conf_merge_ptr_value ngx_conf_merge_uint_value ngx_conf_merge_msec_value ngx_conf_merge_sec_value等等 。
下面来看一下 hello 模块的模块上下文的定义,加深一下印象 。


推荐阅读