December 24th Tuesday 2009

Nginx (二) Mail模块中的配置信息解析

 

因为http模块比较复杂,我选择读mail模块,也涉及到stmp协议。

 

ngx_mail_block()函数开始。

 

原型如下:

static char * ngx_mail_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

 

ngx_conf_t *cf 实际上来自于ngx_init_cycle()函数中定义的conf对象,经由ngx_conf_param() -> ngx_conf_parse() -> ngx_conf_handler()一路传下来的。

 

ngx_command_t *cmd 实际上是mail模块中的command对象;

 

void *conf  mail模块的configure上下文。由ngx_conf_handler()中取得模块的上下文指针传给ngx_mail_block()

 

ngx_mail_block() 一开始就创建为自己的配置信息上下文申请空间。下面的代码比较有意思。

*(ngx_mail_conf_ctx_t **) conf = ctx;

conf当成了指向ngx_mail_conf_ctx结构体指针的指针。

接着为所有mail模块计数并建立索引。

分别为main_confsrv_conf配置上下文申请空间。注意下面代码中可看出,这是两张表每个mail模块都可以根据索引找到自己的main_confsrv_conf

ctx->main_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_mail_max_module);

ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_mail_max_module);

然后,再循环一次,调用每个mail模块中的create_main_conf()create_srv_conf()钩子。这两个钩子的主要作用是模块依自己所需的结构体大小申请空间。成功后,将所申请空间的地址存入main_confsrv_conf对应的表项中。如:

if (module->create_main_conf) {

            ctx->main_conf[mi] = module->create_main_conf(cf);

            if (ctx->main_conf[mi] == NULL) {

                return NGX_CONF_ERROR;

            }

        }

接着就是mail{}块中配置参数的解析。

/* parse inside the mail{} block */

 

    pcf = *cf;

    cf->ctx = ctx;

 

    cf->module_type = NGX_MAIL_MODULE;

    cf->cmd_type = NGX_MAIL_MAIN_CONF;

    rv = ngx_conf_parse(cf, NULL);

 

    if (rv != NGX_CONF_OK) {

        *cf = pcf;

        return rv;

    }

再次调用ngx_conf_parse()之前,对cfmodule_typecmd_type进行了设定。调用了ngx_conf_parse()之后,cf包含从配置文件中指令传过来的参数。

再次循环,调用每个模块中init_main_conf()merge_srv_conf()钩子。调用merge_srv_conf()钩子时,将ngx_mail_core_main_conf_t结构中servers数组中的所有元素和全局的srv_conf数组中的所有元素传入merge_srv_conf()函数中。

 

注意:在配置参数的解析之前有下面一句:

pcf = *cf;

 

merge结束后又有下面的一句:

*cf = pcf;

别外在init_main_conf()merge_srv_conf()钩子调用失败时,也有*cf = pcf;表示维持原有的cf不变。也就是说,每个mail模块的init_main_conf()merge_srv_conf()钩子调用不会影响到其他模块对cf的调用。失败也是一样。

 

创建一个ports数组,4个成员,将监听着的端口存入ports数组,并且保证端口号没有重复。每个端口可以有两个地址。参考ngx_mail_add_ports()函数的代码即可,不难看懂。

最后以ngx_mail_optimize_servers(cf, &ports);调用结束。

你可能感兴趣的:(nginx,Module,command,cmd,null,merge)