概述
分析完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
最后
以上就是爱听歌月饼为你收集整理的[nginx源码分析]配置解析(http作用域)的全部内容,希望文章能够帮你解决[nginx源码分析]配置解析(http作用域)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复