说在前面:
本文的讨论基于的nginx版本是1.2.1。
文章对于nginx的一些背景知识(如什么是模块,上下文等)没有过多提及,本文适合对nginx有一定了解的同学。
ngx_conf_t *cf; 做过nginx模块开发,或者是有学习过nginx源码的同学会对这个结构体非常眼熟了。
ngx_cycle.c:251 conf.ctx = cycle->conf_ctx;
ctx(context)在nginx里随处可见,字面理解是上下文;在nginx里,ctx保存的每个模块的配置结构.
cycle->conf_ctx是一个四重指针,为什么需要四重指针?希望读完本文,会对你理解有一定帮助。
nginx配置文件nginx.conf(文章会围绕这个配置文件,分析nginx解析并保存模块上下文的过程)
1 http { 2 resolver 8.8.8.8; 3 4 server 5 { 6 listen 80; 7 server_name dcshi.com 8 root /data/html 9 10 location /a 11 { 12 set $foo $bar; 13 14 return 200; 15 } 16 17 location /b.html 18 { 19 root /opt/html; 20 } 21 22 } 23 24 server 25 { 26 listen 80; 27 server_name s2.dcshi.com 28 29 location /a {} 30 31 location /b {} 32 } 33 }
与上述配置文件对应的模块上下文(ctx)架构图:
215 for (i = 0; ngx_modules[i]; i++) { 216 if (ngx_modules[i]->type != NGX_CORE_MODULE) { 217 continue; 218 } 219 220 module = ngx_modules[i]->ctx; /* 如果是核心模块,而且有定义了create_conf,则调用模块的create_conf来创建上下文结构 */ 222 if (module->create_conf) { 223 rv = module->create_conf(cycle); 224 if (rv == NULL) { 225 ngx_destroy_pool(pool); 226 return NULL; 227 } 228 cycle->conf_ctx[ngx_modules[i]->index] = rv; 229 } 230 }
2)ngx_cycle.c
/* * 调取ngx_conf_parse开始解析配置文件(nginx.conf),ngx_conf_parse是一个很通用的函数。 * 参数二是一个文件名,如果传入NULL,则解析当前的block配置。{ }配置文件里两花括号定义一个block。 * / 268 if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) { 269 environ = senv; 270 ngx_destroy_cycle_pools(&conf); 271 return NULL; 272 }
3)ngx_conf_file.c:
/* * 如果指令指定了handler函数,则直接调用 * cf->handler 什么时候不为NULL?后续再讨论。 */ 222 if (cf->handler) { 223 224 /* 225 * the custom handler, i.e., that is used in the http's 226 * "types { ... }" directive 227 */ 228 229 rv