Nginx-------配置文件解析ngx_conf_handler

配置文件解析的一般函数是ngx_conf_handler,

 static ngx_int_t

ngx_conf_handler(ngx_conf_t *cf,ngx_int_t last)

参数last是ngx_conf_read_token解析的返回结果。强调一点的是,cf->args中已经保存了我们需要的各个参数。

对于不同的命令类型有不同的处理,


(1)  NGX_DIRECT_CONF

if (cmd->type & NGX_DIRECT_CONF) {
    ngx_conf_log_error(NGX_LOG_DEBUG, cf, 0,"NGX_DIRECT_CONF");                                                                
    conf = ((void **) cf->ctx)[ngx_modules[i]->index];

}

对于那些游离于{}之外的配置,一般属于ngx_core_conf_t的配置内容,
在ngx_init_cycle的时候已经对NGX_CORE_MODULE类型的模块进行了初始化(模块需要有init函数),直接去数组元素作为配置数据指针

这里根据配置信息,set函数会做配置结构内中成员的赋值。

ngx_init_cycle() {
	...
	...
	...
	cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));
	if (cycle->conf_ctx == NULL) {
		ngx_destroy_pool(pool); 
		return NULL;
	}  
	...
	...
	...
	for (i = 0; ngx_modules[i]; i++) {
		if (ngx_modules[i]->type != NGX_CORE_MODULE) {
			continue;
		}

		module = ngx_modules[i]->ctx;

		if (module->create_conf) {
			rv = module->create_conf(cycle);
			if (rv == NULL) {
				ngx_destroy_pool(pool);
				return NULL;
			}
			/*ngx_modules[i]->index had been set before function ngx_int_cycle
			 * only index 0,6,7 will be excute here*/
			cycle->conf_ctx[ngx_modules[i]->index] = rv;//conf_ctx存的直接就是模块的ctx
		}
	}
}
(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) other cmd types

     如在event block里面的use epoll 、worker_connections,

     在event block命令处理函数ngx_events_block里面,先分配了event对应的存储配置的ctx,然后在这个ctx上分配出属于event模块的两个指针数组


 

然后在解析use epoll和worker_connections命令的时候就是调用了这个处理函数,cf->ctx就是上图中的Event ctx,conf数组就是对应的两个数组ngx_event_conf_t和ngx_epoll_conf_t

if (cf->ctx) {
	/*confp is where stores specific configure pointer array*/
	/*use epoll ?worker_connectinos ?????????*/
	confp = *(void **) ((char *) cf->ctx + cmd->conf);

	if (confp) {
		/**/ 
		conf = confp[ngx_modules[i]->ctx_index];
	}    
}  


Nginx 模块开发中,模块初始化的核心任务之一是将请求处理函数添加到 HTTP 请求处理的各个阶段。Nginx 采用多阶段处理机制来处理 HTTP 请求,开发者通常将自定义处理逻辑插入到特定阶段,例如 `content` 阶段。 模块初始化通常通过模块的 `ctx` 结构体定义,并在模块的初始化函数中注册请求处理函数。以下是一个典型的模块初始化结构: ```c static ngx_http_module_t ngx_http_hello_module_ctx = { NULL, /* preconfiguration */ ngx_http_hello_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ NULL, /* create server configuration */ NULL, /* merge server configuration */ NULL, /* create location configuration */ NULL /* merge location configuration */ }; ``` 其中,`ngx_http_hello_init` 是模块的初始化函数,通常用于注册请求处理阶段的回调函数。要将处理函数添加到 `content` 阶段,需要通过模块的命令结构体指定处理函数,或在模块初始化时动态添加。 以下是一个将处理函数添加到 `content` 阶段的示例代码: ```c static ngx_int_t ngx_http_hello_init(ngx_conf_t *cf) { ngx_http_handler_pt *h; ngx_http_core_main_conf_t *cmcf; cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers); if (h == NULL) { return NGX_ERROR; } *h = ngx_http_hello_content_handler; return NGX_OK; } ``` 上述代码中,`ngx_http_hello_content_handler` 是自定义的请求处理函数,其定义如下: ```c static ngx_int_t ngx_http_hello_content_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_buf_t *b; ngx_chain_t out; if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) { return NGX_HTTP_NOT_ALLOWED; } rc = ngx_http_discard_request_body(r); if (rc != NGX_OK) { return rc; } r->headers_out.content_type.len = sizeof("text/plain") - 1; r->headers_out.content_type.data = (u_char *)"text/plain"; b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); if (b == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } b->pos = (u_char *)"Hello, world!"; b->last = b->pos + sizeof("Hello, world!") - 1; b->memory = 1; b->last_buf = 1; out.buf = b; out.next = NULL; r->headers_out.status = NGX_HTTP_OK; rc = ngx_http_send_header(r); if (rc == NGX_ERROR || rc > NGX_OK) { return rc; } return ngx_http_output_filter(r, &out); } ``` 通过这种方式,开发者可以将自定义的处理函数插入到 Nginx 的请求处理流程中,从而实现特定的业务逻辑[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值