[nginx源码分析]配置解析(http作用域)

分析完events后,开始分析http、sever、location模块。

http上下文主要是创建三个用于保存每一个模块设置的变量结构,每个模块都可以保存变量到http三个数组指针中(main、server、location),每个模块的索引是模块的ctx_index变量指定在三个数组中的位置

核心代码:

     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));               //首先分配一个http上下文变量,里面是指针的指针,因为后面分配数组都是void* 指针数组
      if (ctx == NULL) {
          return NGX_CONF_ERROR;
      }
  
      *(ngx_http_conf_ctx_t **) conf = ctx;
  
  
      /* count the number of the http modules and set up their indices */
  
      ngx_http_max_module = 0;
      for (m = 0; ngx_modules[m]; m++) {
          if (ngx_modules[m]->type != NGX_HTTP_MODULE) {                      //上层是NGX_CORE_MODULE,这层模块是NGX_HTTP_MODULE,表示后面的都是http范围需要设置的东西
              continue;
          }
  
          ngx_modules[m]->ctx_index = ngx_http_max_module++;                  //设置NGX_HTTP_MODULE模块的索引位置.
      }

其中ngx_http_conf_ctx_t变量如下:

 typedef struct {
      void        **main_conf;
      void        **srv_conf;
      void        **loc_conf;
  } ngx_http_conf_ctx_t;

其中main_conf 指向ngx_http_max_module个void*数组、srv_conf指向ngx_http_max_module个void*数组、loc_conf会指向ngx_http_max_module个void*数组。

整个cycle->ctx如下:

技术分享

由于会越画越大,所有就把http的直接拿出来,上面是一个整体布局。

然后遍历http模块(即模块type是NGX_HTTP_MODULE)如果存在回调函数create_main_conf、create_srv_conf、create_loc_conf,就会调用每个http模块的此回调方法。

比如ngx_http_core_module模块相应方法回调如下:

ngx_http_core_create_main_conf

创建ngx_http_core_main_conf_t结构保存在http->ctx->main_conf[0]上面

 typedef struct {                                                                                                                                         
     ngx_array_t                servers;         /* ngx_http_core_srv_conf_t */
     ngx_http_phase_engine_t    phase_engine;
     ngx_hash_t                 headers_in_hash;
     ngx_hash_t                 variables_hash;
     ngx_array_t                variables;       /* ngx_http_variable_t */
     ngx_uint_t                 ncaptures;
     ngx_uint_t                 server_names_hash_max_size;
     ngx_uint_t                 server_names_hash_bucket_size;
     ngx_uint_t                 variables_hash_max_size;
     ngx_uint_t                 variables_hash_bucket_size;
     ngx_hash_keys_arrays_t    *variables_keys;
     ngx_array_t               *ports;
     ngx_uint_t                 try_files;       /* unsigned  try_files:1 */
     ngx_http_phase_t           phases[NGX_HTTP_LOG_PHASE + 1];
 } ngx_http_core_main_conf_t;

创建ngx_http_core_srv_conf_t结构保存在http->ctx->srv_conf[0]上面

 typedef struct {
     /* array of the ngx_http_server_name_t, "server_name" directive */
     ngx_array_t                 server_names;
     /* server ctx */
     ngx_http_conf_ctx_t        *ctx;
     ngx_str_t                   server_name;
     size_t                      connection_pool_size;
     size_t                      request_pool_size;
     size_t                      client_header_buffer_size;
     ngx_bufs_t                  large_client_header_buffers;
     ngx_msec_t                  client_header_timeout;
     ngx_flag_t                  ignore_invalid_headers;
     ngx_flag_t                  merge_slashes;
     ngx_flag_t                  underscores_in_headers;
     unsigned                    listen:1;
#if (NGX_PCRE)
     unsigned                    captures:1;
#endif 
    ngx_http_core_loc_conf_t  **named_locations;
} ngx_http_core_srv_conf_t;

创建ngx_http_core_loc_conf_s结构保存在http->ctx->loc_conf[0]上面

由于代码太长只截取一部分代码

 struct ngx_http_core_loc_conf_s {
     ngx_str_t     name;          /* location name */
 #if (NGX_PCRE)
     ngx_http_regex_t  *regex;
 #endif
     unsigned      noname:1;   /* "if () {}" block or limit_except */
     unsigned      lmt_excpt:1;
     unsigned      named:1;
     unsigned      exact_match:1;
     unsigned      noregex:1;
     unsigned      auto_redirect:1;
 #if (NGX_HTTP_GZIP)
     unsigned      gzip_disable_msie6:2;
 #if (NGX_HTTP_DEGRADATION)
     unsigned      gzip_disable_degradation:2;
 #endif
 #endif
     ngx_http_location_tree_node_t   *static_locations;
 #if (NGX_PCRE)
     ngx_http_core_loc_conf_t       **regex_locations;
 #endif 
     /* pointer to the modules' loc_conf */
     void        **loc_conf;
     uint32_t      limit_except;
     void        **limit_except_loc_conf;
     ngx_http_handler_pt  handler;......
</pre><pre code_snippet_id="660923" snippet_file_name="blog_20150507_7_7568482" name="code" class="cpp">

挂载之后,整个结构如下(只分析了ngx_http_core_module)

技术分享

然后ngx_http_block->ngx_conf_parse 对ngx_conf_parse进行间接回调,不同的是,这个时候,把上下文修改为http的了,如下核心代码:

//设置模块为NGX_HTTP_MODULE
		cf->module_type = NGX_HTTP_MODULE;                                              
//开始分析的是主配置
     cf->cmd_type = NGX_HTTP_MAIN_CONF;                                              
     rv = ngx_conf_parse(cf, NULL);

根据配置参数,分析到include会调用模块ngx_conf_module::ngx_conf_include函数

然后调用ngx_conf_parse,解析include文件,因为配置文件中include mine.types文件,

所以调用ngx_http_core_module中的types映射的方法ngx_http_core_types,include命令仅仅是调用ngx_conf_parse(cf, &file),把include所在模块的conf和include的文件传给ngx_conf_parse,进行文件解析,文件中的具体命令还是一样会被一步步的解析出来。include命令相当于把多个文件分开了,比如多个server配置写到不同的配置文件中,方便修改和管理。

 static char *
 ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
     ngx_http_core_loc_conf_t *clcf = conf;
     char        *rv;
     ngx_conf_t   save;
     if (clcf->types == NULL) {
         clcf->types = ngx_array_create(cf->pool, 64, sizeof(ngx_hash_key_t));
         if (clcf->types == NULL) {
             return NGX_CONF_ERROR;
         }
     }
     save = *cf;
     cf->handler = ngx_http_core_type;//设置mine.types文件回调
     cf->handler_conf = conf;//此conf为ctx->loc_conf[0],的conf
     rv = ngx_conf_parse(cf, NULL);                                                                                                                                
     *cf = save;//还原为原来的conf
     return rv;
}

对mine.types每解析一行(ngx_conf_read_token),就保存在ctx->loc_conf[0].types里面

然后分析到default_type

{	ngx_string("default_type"),      
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_str_slot,
       NGX_HTTP_LOC_CONF_OFFSET,                                                                                                                                   
       offsetof(ngx_http_core_loc_conf_t, default_type),
       NULL },

保存在ctx->loc_conf[0].default_type里面

同理sendfile command

     { ngx_string("sendfile"),                                                                                                                                            
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
                          |NGX_CONF_FLAG,
       ngx_conf_set_flag_slot,
       NGX_HTTP_LOC_CONF_OFFSET,
       offsetof(ngx_http_core_loc_conf_t, sendfile),
       NULL },

保存在ctx->loc_conf[0].sendfile里面

同理keepalive_timeout保存在ctx->loc_conf[0].keepalive_timeout




郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。