ngx conf相关



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


为什么传进来的conf 为空 ?


//定义中
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;
};






static ngx_command_t ngx_http_xxm_commands[] = {
     {
ngx_string("xxm"),  
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_NOARGS,
      ngx_http_xxm, 
      //0,
      NGX_HTTP_LOC_CONF_OFFSET,
      0,
      NULL 
     },
     ngx_null_command
     };






在解析中在ngx_conf_handler中


这里分3种情况:


(1)  NGX_DIRECT_CONF


对于那些游离于{}之外的配置,一般属于ngx_core_conf_t的配置内容,在ngx_init_cycle的时候已经对
NGX_CORE_MODULE类型的模块进行了初始化(模块需要有init函数),这里根据配置信息,set函数会做配置结
构内中成员的赋值。


(2)  NGX_MAIN_CONF


这样的配置包括event,http等,他们没有init函数,所以实际的空间分配需要在set函数内完成,于是就有了:


conf =&(((void **) cf->ctx)[ngx_modules[i]->index]); //取指针的地址


rv =cmd->set(cf, cmd, conf);                                     // 指针在函数内被赋值


set中conf参数是一个二重指针,这也就有个之后在ngx_http_block中的语句:


ctx =ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));


 *(ngx_http_conf_ctx_t **) conf = ctx;


(3)其他


其实这里的“其他”,主要是一些server和location的类型的command,这些command大量的集中于http的相关配置中。


我们先来看ngx_http_conf_ctx_t  (更低的一层)
结构:


typedefstruct {


    void       **main_conf;


    void       **srv_conf;


    void       **loc_conf;


}ngx_http_conf_ctx_t;


这里有一点需要交代的是,像http模块下,有一些所谓的子模块,而这些子模块基本上都是http中server或者location中的一些配置。这些配置通过模块中ctx_index,以数组的形式,将他们的配置结构的指针保存在srv_conf或loc_conf中,这就是他们的类型为什么会是void **。


我们来看这句:


confp =*(void **) ((char *) cf->ctx + cmd->conf);


我相信这一句是比较难懂的,实际上cmd->conf是成员在结构体中的偏移量。这里举个例子就明白了:


假设我们在32位机下,cmd->conf为8,cf->ctx的地址为0x008004A2,那么cf->ctx+cmd->conf =


0x008004A2+ 8 = 0x008004AA,你应该晓得这个地址里面放的是什么,所以外面做了一个类型强转,(void **),这个转换告诉我们,0x008004AA是个二级指针值,这个地址下放的是一个指针,现在我们需要里面的指针,于是就有了*(void **)。


完整的过程是这样的:


//得到一个指针,到底是几维呢?无所谓,这里我们是拿它当二维指针来用的,为啥呢?


// 前面说过了,他们是子模块配置的指针的数组!


confp =*(void **) ((char *) cf->ctx + cmd->conf);


   conf = confp[ngx_modules[i]->ctx_index];     // 拿到配置结构   


rv =cmd->set(cf, cmd, conf);               // 做处理


最后说明一下,开始提到的那个void ****类型成员,使用这种类型的原因我们可以在ngx_events_block函数中找到答案。








这个cf就是cycle中的


// 命令是在此解析的  至于create_loc  merge_loc 在  http_block中
static ngx_int_t
ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)
{
.......
   
conf = NULL;


        if (cmd->type & NGX_DIRECT_CONF) 
        {
                conf = ((void **) cf->ctx)[ngx_modules[i]->index];
        } 
        else if (cmd->type & NGX_MAIN_CONF) 
        {
                conf = &(((void **) cf->ctx)[ngx_modules[i]->index]);
        }
        else if (cf->ctx) 
        {    
                confp = *(void **) ((char *) cf->ctx + cmd->conf);
                if (confp) 
                {
                    conf = confp[ngx_modules[i]->ctx_index];
                }
         }
    rv = cmd->set(cf, cmd, conf);
     
    ......
}








struct ngx_cycle_s 
{
     ......
    void                  ****conf_ctx;
              ......
};


// ngx_conf_t *cf 是什么?




nginx 配置文件 


ngx_cycle_t *
ngx_init_cycle(ngx_cycle_t *old_cycle)
{
    ......

    conf.ctx = cycle->conf_ctx;
    conf.cycle = cycle;
    conf.pool = pool;
    conf.log = log;
    conf.module_type = NGX_CORE_MODULE;
    conf.cmd_type = NGX_MAIN_CONF;
    if (ngx_conf_param(&conf) != NGX_CONF_OK) {
        environ = senv;
        ngx_destroy_cycle_pools(&conf);
        return NULL;
    }


    if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
        environ = senv;
        ngx_destroy_cycle_pools(&conf);
        return NULL;
    }
    ......
}










char *
ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
{
......
  for ( ;; ) {
        rc = ngx_conf_read_token(cf);


        /*
         * ngx_conf_read_token() may return
         *
         *    NGX_ERROR             there is error
         *    NGX_OK                the token terminated by ";" was found
         *    NGX_CONF_BLOCK_START  the token terminated by "{" was found
         *    NGX_CONF_BLOCK_DONE   the "}" was found
         *    NGX_CONF_FILE_DONE    the configuration file is done
         */


        if (rc == NGX_ERROR) {
            goto done;
        }


        if (rc == NGX_CONF_BLOCK_DONE) {


            if (type != parse_block) {
                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unexpected \"}\"");
                goto failed;
            }


            goto done;
        }


        if (rc == NGX_CONF_FILE_DONE) {


            if (type == parse_block) {
                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                   "unexpected end of file, expecting \"}\"");
                goto failed;
            }


            goto done;
        }


        if (rc == NGX_CONF_BLOCK_START) {


            if (type == parse_param) {
                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                   "block directives are not supported "
                                   "in -g option");
                goto failed;
            }
        }


        /* rc == NGX_OK || rc == NGX_CONF_BLOCK_START */


        if (cf->handler) {


            /*
             * the custom handler, i.e., that is used in the http's
             * "types { ... }" directive
             */


printf("%s \n",(*cf->handler));
            rv = (*cf->handler)(cf, NULL, cf->handler_conf);
            if (rv == NGX_CONF_OK) {
                continue;
            }


            if (rv == NGX_CONF_ERROR) {
                goto failed;
            }



            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, rv);


            goto failed;
        }




        rc = ngx_conf_handler(cf, rc);   


        if (rc == NGX_ERROR) {
            goto failed;
        }
    }

......
}








static char *
ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{


}
//ngx_http_block函数!遍历每个http类型的模块,调用模块上下文ngx_http_module_t
中的init_main_conf钩子初始化模块对应的main_conf配置信息,handler位置等。




组织结构图: 
   http://tech.uc.cn/?p=300


重要结构:    


 struct ngx_conf_s {
    char                 *name;
    ngx_array_t          *args;


    ngx_cycle_t          *cycle;
    ngx_pool_t           *pool;
    ngx_pool_t           *temp_pool;
    ngx_conf_file_t      *conf_file;
    ngx_log_t            *log;


    void                 *ctx;
    //重要 在此中即为 ****
    
    ngx_uint_t            module_type;
    ngx_uint_t            cmd_type;


    ngx_conf_handler_pt   handler;
    char                 *handler_conf;
};




重要全局变量:


    ngx_uint_t     ngx_max_module;
    ngx_module_t  *ngx_modules[];


参考文档: http://www.linuxidc.com/Linux/2011-11/46437.htm



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值