nginx http模块中配置的实现和解析---1

配置的主要函数流程:

下面是http配置解析的函数流程:
ngx_http_block   #ngx_string("http"),初始化总的config,然后传递
------ngx_http_init_phases
------ngx_http_init_phase_handlers
       ------ngx_http_core_find_config_phase
               ------ngx_http_core_find_location
                       ------ngx_http_core_find_static_location
                       ------ngx_http_core_find_location
               ------ngx_http_clear_location
------ngx_http_init_locations      # build queue and insert  location
------ngx_http_init_static_location_trees  # 创建location树的结构
       ------ngx_http_join_exact_locations
       ------ngx_http_create_locations_list
       ------ngx_http_create_locations_tree

函数解析:

static ngx_command_t ngx_http_commands[] = {

{ ngx_string("http"),


NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,

//代表这个指令只能放在NGX_MAIN_CONF,就是配置文件的主配置中,并且不带参数

//NGX_CONF_BLOCK代表这是一个块域,就是后面跟{ }

//关于这个宏定义,可以参考《深入理解nginx》第120页


ngx_http_block,  //回调方法,nginx预先设置了14个解析配置的方法,参考上书121


0,  // 配置项所处内存的相对偏移位置

//一般可以属于main_conf,srv_conf,loc_conf,参考123


0,  //在结构体中的偏移位置,有一个宏定义,offsetof(xxx_loc_conf, a),可以像这样子设置,取出偏移值


NULL }, //自定义,还有待深究,上书125

ngx_null_command
};

这个结构体代表ngx_http模块只有一个指令,就是http指令。依次读取并且解析的nginx.conf文件中如果包含了http,那么,就会调用ngx_http_block这个函数。

ngx_http_block这个函数是核心函数,下面对着代码进行解析。 static char *

ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
。。。。。。 // 省略变量定义

/* the main http context */

ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));  /*分配上下文内存,基本上每个模块都有上下文,她不用于持久保存,但是,在模块初始化并且配置main_conf,srv_conf,loc_conf时非常的重要。*/

。。。。。。

*(ngx_http_conf_ctx_t **) conf = ctx;  //让conf指向ctx,也就是保存了ctx,conf来源于上层的解析,详情请跟踪源代码


/* count the number of the http modules and set up their indices */

ngx_http_max_module = 0;   //一个全局变量,主要用于统计http模块
for (m = 0; ngx_modules[m]; m++) {
if (ngx_modules[m]->type != NGX_HTTP_MODULE) {

//自己写的module,需要注明他的类型NGX_HTTP_MODULE,

例如:/******

ngx_module_t ngx_http_core_module = {
NGX_MODULE_V1,
&ngx_http_core_module_ctx, /* module context */
ngx_http_core_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */       //注明类型,这样她就属于http模块
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};

******/


continue;
}

ngx_modules[m]->ctx_index = ngx_http_max_module++;
}

//下面就分配三大结构体,参考http://www.dcshi.com/?p=333

//http://www.dcshi.com/wp-content/uploads/2013/03/nginx_ctx4.jpeg,这个图比较清楚

//的描述了三大结构的关系,虽然,还待深究
/* the http main_conf context, it is the same in the all http contexts */

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

/*
* the http null srv_conf context, it is used to merge
* the server{}s' srv_conf's
*/

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

/*
* the http null loc_conf context, it is used to merge
* the server{}s' loc_conf's
*/

ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);

/*
* create the main_conf's, the null srv_conf's, and the null loc_conf's
* of the all http modules
*/

for (m = 0; ngx_modules[m]; m++) {
if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
continue;
}

module = ngx_modules[m]->ctx;
mi = ngx_modules[m]->ctx_index;

//初始化三大结构体

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

if (module->create_srv_conf) {
ctx->srv_conf[mi] = module->create_srv_conf(cf);
}

if (module->create_loc_conf) {
ctx->loc_conf[mi] = module->create_loc_conf(cf);
}

pcf = *cf;  // 保存cf的内容
cf->ctx = ctx; //修改ctx

//引入一个结构体

/*********

typedef struct {
ngx_int_t (*preconfiguration)(ngx_conf_t *cf);
ngx_int_t (*postconfiguration)(ngx_conf_t *cf); // 上书78

void *(*create_main_conf)(ngx_conf_t *cf);
char *(*init_main_conf)(ngx_conf_t *cf, void *conf);

void *(*create_srv_conf)(ngx_conf_t *cf);
char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);

void *(*create_loc_conf)(ngx_conf_t *cf);
char *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);
} ngx_http_module_t;

这个结构体非常重要,规定了所有属于http的模块必须实现的结构体

主要是创建和合并配置

*******/

for (m = 0; ngx_modules[m]; m++) {
if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
continue;
}

module = ngx_modules[m]->ctx;

if (module->preconfiguration) {

/*******

nginx几乎每个模块都可以定义自己的变量,每个模块都是通过自己的preconfiguration把变量统一规划起来的,这是我参考的http://blog.csdn.net/opens_tym/article/details/9956093

**********/
if (module->preconfiguration(cf) != NGX_OK) {
return NGX_CONF_ERROR;
}
}
}

/* parse inside the http{} block */

cf->module_type = NGX_HTTP_MODULE;
cf->cmd_type = NGX_HTTP_MAIN_CONF;


/******

这个函数是非常重要,是解析配置文件的核心函数

********/

rv = ngx_conf_parse(cf, NULL); 

/*
* init http{} main_conf's, merge the server{}s' srv_conf's
* and its location{}s' loc_conf's
*/

cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
cscfp = cmcf->servers.elts;

/****这儿代表这server数组,这个在下面会用到******/


for (m = 0; ngx_modules[m]; m++) {
if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
continue;
}

module = ngx_modules[m]->ctx;
mi = ngx_modules[m]->ctx_index;

/* init http{} main_conf's */

if (module->init_main_conf) {
rv = module->init_main_conf(cf, ctx->main_conf[mi]);

/********合并所以模块的main函数配置*********/
}

rv = ngx_http_merge_servers(cf, cmcf, module, mi);  //合并server配置项

/*******合并完成后,cmcf中存放server数组*********/
。。。。。。


/* create location trees */

for (s = 0; s < cmcf->servers.nelts; s++) {

/********取到每个server的ctx,然后取出loc配置******/

clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];


初始化location和static location,这两个的差别,还待深究

if (ngx_http_init_locations(cf, cscfp[s], clcf) != NGX_OK) {

if (ngx_http_init_static_location_trees(cf, clcf) != NGX_OK) {

/*********初始化http的7个阶段***********/
if (ngx_http_init_phases(cf, cmcf) != NGX_OK) {
return NGX_CONF_ERROR;
}

if (ngx_http_init_headers_in_hash(cf, cmcf) != NGX_OK) {
return NGX_CONF_ERROR;
}


for (m = 0; ngx_modules[m]; m++) {
if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
continue;
}

module = ngx_modules[m]->ctx;

if (module->postconfiguration) {
if (module->postconfiguration(cf) != NGX_OK) {
return NGX_CONF_ERROR;
/********解析完配置后的回调函数*********/

if (ngx_http_variables_init_vars(cf) != NGX_OK) {
return NGX_CONF_ERROR;
}

/*
* http{}'s cf->ctx was needed while the configuration merging
* and in postconfiguration process
*/

*cf = pcf;  

/********恢复cf的配置***********/


if (ngx_http_init_phase_handlers(cf, cmcf) != NGX_OK) {
return NGX_CONF_ERROR;
}


/* optimize the lists of ports, addresses and server names */

if (ngx_http_optimize_servers(cf, cmcf, cmcf->ports) != NGX_OK) {

/********这个函数也比较重要,下节在介绍**********/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值