[nginx源码分析]配置解析(server作用域)
2015-05-07 13:12
761 查看
然后进入到server
server命令在ngx_http_core_module中,如下
{ ngx_string("server"), NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_MULTI|NGX_CONF_NOARGS, ngx_http_core_server, 0, 0, NULL },
ngx_http_core_server首先创建一个和ngx_http_block函数一样的上下文结构
typedef struct { void **main_conf; void **srv_conf; void **loc_conf; } ngx_http_conf_ctx_t;
其中main_conf指向http上线文的main_conf
srv_conf和loc_conf都是自己创建的新的结构,包括后面进行的create_srv_conf和create_loc_conf都是和在ngx_http_block都是一致的。
同时把server信息push到http上下文中
cscf = ctx->srv_conf[ngx_http_core_module.ctx_index]; //这里返回的是一个srv_conf结构, cscf->ctx = ctx; //把这个结构中的ctx上下文,保存在这个srv_conf中的ctx中 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; //获取ngx_http_module::main_conf[server]一个,然后把这个结构保存在server中 cscfp = ngx_array_push(&cmcf->servers); if (cscfp == NULL) { return NGX_CONF_ERROR; } *cscfp = cscf; push到http_ctx->main_conf[0].server里面 然后保存conf,修改成server上下文 pcf = *cf; //保存上层的http上下文,准备换成server上下文 cf->ctx = ctx; //这里把上下文换掉了 cf->cmd_type = NGX_HTTP_SRV_CONF; rv = ngx_conf_parse(cf, NULL);
进行回调
然后配置文件解析到listen,listen是在ngx_http_core_module中
{ ngx_string("listen"), NGX_HTTP_SRV_CONF|NGX_CONF_1MORE, ngx_http_core_listen, NGX_HTTP_SRV_CONF_OFFSET, 0, NULL },
ngx_http_core_listen(ngx_conf_t *cf,ngx_command_t *cmd, void *conf)
//其中cf为上面server环境中设置后的,cmd为listen cmd,conf为server_ctx->srv_conf[0]
ngx_http_core_listen回调函数主要是解析listen后面的参数,构造lsopt结构,然后调用ngx_http_add_listen,此函数首先获取main_conf
cmcf =ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
然后遍历cmcf->ports
port = cmcf->ports->elts; for (i = 0; i < cmcf->ports->nelts; i++) { if (p != port[i].port || sa->sa_family != port[i].family) { continue; } /* a port is already in the port list */ //已经存在相同的port和family return ngx_http_add_addresses(cf, cscf, &port[i], lsopt); }
其中cmcf->ports是数组,遍历每一个数组,相当于key为port and family,如果有相同的地址,那么就调用ngx_http_add_addresses加入相应的port,如果没有那么就从数组里面分配一个调用ngx_http_add_addresses加入。ngx_http_add_address函数,首先遍历该port里面的server address,如果发现存在地址也相同的就加入到相同的addr->servers,如果说该port下没有相同的地址,那么就新生成一个addr,加入到addr->servers里。
整个cmcf->ports结构组织如下:
cmcf->ports /*ngx_array_t 数组中元素类型是ngx_http_conf_port_t*/ family /*ngx_int_t 网络类型*/ port /* int_port_t 端口*/ addrs /* ngx_array_t 数组中元素类型是ngx_http_conf_addr_t*/ ngx_http_listen_opt_t opt; ngx_hash_t hash; ngx_hash_wildcard_t *wc_head; ngx_hash_wildcard_t *wc_tail; ngx_uint_t nregex; ngx_http_server_name_t *regex; ngx_http_core_srv_conf_t *default_server; ngx_array_t servers;/*数组类型为ngx_http_core_srv_conf_t, 也就是当前server上下文*/
整个函数流程如下:
server_name命令如下:
{ ngx_string("server_name"), NGX_HTTP_SRV_CONF|NGX_CONF_1MORE, ngx_http_core_server_name, NGX_HTTP_SRV_CONF_OFFSET, 0, NULL },
从命令可以看出,上下文是server->srv_conf,因为server_name是在ngx_http_core_module模块所以索引是0,即上下文真实地址是server->srv_conf[0],然后回调函数是ngx_http_core_server_name,函数主要是加入server->srv_conf[0].server_names
struct ngx_http_server_name_s { #if (NGX_PCRE) ngx_http_regex_t *regex; #endif ngx_http_core_srv_conf_t *server; /* 保存当前上下文*/ ngx_str_t name; /*server name*/ };
下面先讲error_page,因为location比较长
{ ngx_string("error_page"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF |NGX_CONF_2MORE, ngx_http_core_error_page, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL },
这样error_page信息,保存在server->loc_conf,因为命令是在ngx_http_core_module里,所以准确的存放位置是server->loc_conf[0],具体代码:
for (i = 1; i < cf->args->nelts - n; i++) { err = ngx_array_push(clcf->error_pages);//增加一个err if (err == NULL) { return NGX_CONF_ERROR; } err->status = ngx_atoi(value[i].data, value[i].len);//设置状态吗 if (err->status == NGX_ERROR || err->status == 499) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid value \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (err->status < 300 || err->status > 599) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "value \"%V\" must be between 300 and 599", &value[i]); return NGX_CONF_ERROR; } err->overwrite = overwrite; if (overwrite == -1) { switch (err->status) { case NGX_HTTP_TO_HTTPS: case NGX_HTTPS_CERT_ERROR: case NGX_HTTPS_NO_CERT: err->overwrite = NGX_HTTP_BAD_REQUEST; default: break; } } err->value = cv; err->args = args; }
相关文章推荐
- [nginx源码分析]配置解析(http作用域)
- [nginx源码解析]配置解析(main作用域)
- [nginx源码分析]配置解析(location作用域)
- Nginx 源码分析-- 模块module 解析执行 nginx.conf 配置文件流程分析 一
- Nginx源码分析 - 主流程篇 - 解析配置文件
- nginx 源码分析 1 - 配置解析
- nginx源码分析--配置文件解析
- [nginx源码分析]配置解析1
- Nginx 源码分析-- 模块module 解析执行 nginx.conf 配置文件流程分析 二
- 在Ubuntu Server上源码安装OpenERP 8.0,并配置wsgi和nginx运行环境
- Tomcat源码分析——SERVER.XML文件的加载与解析
- Nginx源码分析—nginx的配置
- [nginx源码分析]server_name hash
- mybatis源码学习之执行过程分析(2)——config.xml配置文件和mapper.xml映射文件解析过程
- Spring源码分析2 — XML配置文件的解析流程
- Nginx源码解析- http模块分析
- [nginx源码解析]配置解析(event作用域)
- Nginx 模块自主开发六:源码剖析配置文件解析过程
- Nginx源码分析 - HTTP模块篇 - ngx_http_wait_request_handler函数和HTTP Request解析过程
- Nginx源码分析 - Event事件篇 - Event模块和配置的初始化