2018-11-18-Nginx 命令解析 set 函数的说明

对于 ngx_command_t 中 set 的调用,可以参见 ngx_conf_handler 函数节选:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
static ngx_int_t
ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)
{
void *conf, **confp;
......
/* set up the directive's configuration context */
conf = NULL;

// modules[i]->index 是代表模块位置的下标;modules[i]->ctx_index代表在他所属模块组的下标
if (cmd->type & NGX_DIRECT_CONF) {
// 直接区配置结构体使用,将 void **** 转换为 void **
conf = ((void **) cf->ctx)[cf->cycle->modules[i]->index];
} else if (cmd->type & NGX_MAIN_CONF) {
// 配置结构体没有创建,将指针传递进去,创建配置结构体并更新
conf = &(((void **) cf->ctx)[cf->cycle->modules[i]->index]);
} else if (cf->ctx) {
// 使用 cmd->conf 进行二次偏移,取到模块 cmd->conf 类型上下文的实际地址
// cmd->conf 可以取:NGX_HTTP_MAIN_CONF_OFFSET,NGX_HTTP_SRV_CONF_OFFSET,NGX_HTTP_LOC_CONF_OFFSET 等值
confp = *(void **) ((char *) cf->ctx + cmd->conf);
if (confp) {
// 通过组下标找到位置
conf = confp[cf->cycle->modules[i]->ctx_index];
}
}

rv = cmd->set(cf, cmd, conf);

if (rv == NGX_CONF_OK) {
return NGX_OK;
}
......
}

调用 set 时 conf 指针为模块的上下文。

NGX_DIRECT_CONF 由核心模块使用,表示模块需要解析不属于任何 {} 内的全局配置项,需要与 NGX_MAIN_CONF 配合使用。如果只有 NGX_MAIN_CONF 类型,说明存储配置的结构体还没有创建。

ngx_cycle_t 中有成员 conf_ctx 负责维护所有模块的配置结构体。