nginx-0.8.38源码探秘(三)

 

本文档的Copyleft归L.L所有,使用GPL发布,可以自由转载,转载时请务必以超链接形式标明文章原始出处,严禁用于任何商业用途。

email: cc.dd.14@163.com
来源: http://blog.csdn.net/ccdd14

 

 

ngx_http_block函数是对整个HTTP相关模块的构建和初始化。首先映入眼帘的是四个结构:ngx_http_conf_ctx_t,ngx_http_core_loc_conf_t,ngx_http_core_srv_conf_t,ngx_http_core_main_conf_t,理解这些结构的成员可以查看网址:http://wiki.nginx.org/NginxChsHttpCoreModule,thanks wiki again and again。一个ngx_http_core_main_conf_t包含若干ngx_http_core_srv_conf_t,ngx_http_core_srv_conf_t又包含若干ngx_http_core_loc_conf_t。

先创建NGX_HTTP_MODULE模块的索引,最大模块数保存在ngx_http_max_module。遍历类型为NGX_HTTP_MODULE的模块,依次调用它们注册的create_main_conf,create_srv_conf,create_loc_conf钩子,它们的作用基本上都是创建相应的conf结构。

接着遍历调用preconfiguration钩子,添加各模块需要的variables到ngx_http_core_main_conf_t的hash表(variables_keys)里。再一次见到ngx_conf_parse函数,遍历调用各模块commands的set钩子,注意,cf->module_type = NGX_HTTP_MODULE,cf->cmd_type = NGX_HTTP_MAIN_CONF,看看一些重要的set钩子:

  1. ngx_http_core_module模块,哇!好多钩子:(1)ngx_http_core_server,它再次遍历NGX_HTTP_MODULE模块,再次调用注册的create_srv_conf,create_loc_conf钩子,接着将cf->cmd_type = NGX_HTTP_SRV_CONF,调用ngx_conf_parse,这样将调用type=NGX_HTTP_SRV_CONF的set钩子。如此又进入ngx_http_core_location,遍历NGX_HTTP_MODULE模块,调用注册的create_loc_conf钩子,解析location配置部分,ngx_http_add_location将解析结果合并,最后cf->cmd_type = NGX_HTTP_LOC_CONF,再调用ngx_conf_parse。有几个NGX_HTTP_LOC_CONF类型的set钩子非常重要:ngx_http_proxy_module模块的ngx_http_proxy_pass,注册了clcf->handler = ngx_http_proxy_handler,而这个handler也注册了大量的用于upstream的钩子;ngx_http_fastcgi_module模块的ngx_http_fastcgi_pass,注册了clcf->handler = ngx_http_fastcgi_handler;ngx_http_memcached_module模块的ngx_http_memcached_pass,注册了clcf->handler = ngx_http_memcached_handler;ngx_http_empty_gif_module模块的ngx_http_empty_gif,注册了clcf->handler = ngx_http_empty_gif_handler;(2)ngx_http_core_types,它注册了cf->handler = ngx_http_core_type,再调用ngx_conf_parse。
  2. ngx_http_upstream_module模块,set钩子------ngx_http_upstream解析Upstream配置部分。首先是遍历NGX_HTTP_MODULE模块,调用注册的create_srv_conf,create_loc_conf钩子,最后cf->cmd_type = NGX_HTTP_UPS_CONF,调用ngx_conf_parse,目前只有ngx_http_upstream_module和ngx_http_upstream_ip_hash_module有这种类型的set钩子;
  3. ngx_http_limit_zone_module模块的set钩子-----ngx_http_limit_zone解析limit_zone配置部分,注册了shm_zone->init = ngx_http_limit_zone_init_zone;
  4. ngx_http_limit_req_module模块的set钩子------ngx_http_limit_req_zone解析limit_req_zone配置部分,注册了shm_zone->init = ngx_http_limit_req_init_zone;
  5. ngx_http_geo_module模块的set钩子------ngx_http_geo_block解析geo配置部分,注册了cf->handler = ngx_http_geo,然后调用ngx_conf_parse;
  6. ngx_http_map_module模块的set钩子------ngx_http_map_block解析map配置部分,注册了两个handler,var->get_handler = ngx_http_map_variable,cf->handler = ngx_http_map,然后调用ngx_conf_parse;
  7. ngx_http_split_clients_module模块的set钩子-----ngx_conf_split_clients_block解析split_clients配置部分,注册了两个handler,var->get_handler = ngx_http_split_clients_variable,cf->handler = ngx_http_split_clients;
  8. ngx_http_referer_module模块的set钩子------ngx_http_valid_referers解析referer配置部分,注册了var->get_handler = ngx_http_referer_variable;
  9. ngx_http_proxy_module模块的set钩子-----ngx_http_proxy_redirect解析proxy_redirect配置部分,注册了ngx_http_proxy_redirect_t结构的handler:pr->handler = ngx_http_proxy_rewrite_redirect_text(或者ngx_http_proxy_rewrite_redirect_text);
  10. ngx_http_charset_filter_module模块的set钩子ngx_http_charset_map_block注册了cf->handler = ngx_http_charset_map,然后调用ngx_conf_parse;
  11. ngx_http_headers_filter_module模块的set钩子-----ngx_http_headers_add注册了ngx_http_header_val_t结构的handler:hv->handler = ngx_http_add_header,以及set = ngx_http_set_headers,ngx_http_set_headers为: 

http配置解析部分遵循着一个层次结构:loc->srv->main,会先将所有的loc(NGX_HTTP_LOC_CONF)解析完成,然后解析所有的srv(NGX_HTTP_SRV_CONF), 最后解析main(NGX_HTTP_MAIN_CONF)。

接着又遍历类型为NGX_HTTP_MODULE的模块,依次调用它们注册的init_main_conf,merge_srv_conf,merge_loc_conf钩子,下面对重要模块进行分析:

  1. ngx_http_core_module模块,init_main_conf的功能是用默认值填充ngx_http_core_main_conf_t结构,merge_srv_conf 合并main和server配置,将监听端口,地址存入数组里,merge_loc_conf合并server和location配置;
  2. ngx_http_upstream_module模块,只注册了init_main_conf钩子,用来分析uptream配置,得到每个后端服务器的权重,超时值等信息,将ngx_http_upstream_headers_in变量注册进来,该变量注册了头部字段的处理函数;

继续遍历类型为NGX_HTTP_MODULE的模块,调用它们注册的postconfiguration钩子,看看几个重要的钩子函数:

  1. ngx_http_log_module模块的钩子是ngx_http_log_init,注册cmcf->phases[NGX_HTTP_LOG_PHASE].handlers=ngx_http_log_handler;
  2. ngx_http_static_module模块的钩子是ngx_http_static_init,注册cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers=ngx_http_static_handler;
  3. ngx_http_autoindex_module模块的钩子是ngx_http_autoindex_init,注册cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers=ngx_http_autoindex_handler;
  4. ngx_http_index_module模块的钩子是ngx_http_index_init,注册cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers=ngx_http_index_handler;
  5. ngx_http_auth_basic_module模块的钩子是ngx_http_auth_basic_init,注册cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers=ngx_http_auth_basic_handler;
  6. ngx_http_access_module模块的钩子是ngx_http_access_init,注册cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers=ngx_http_access_handler;
  7. ngx_http_limit_zone_module模块的钩子是ngx_http_limit_zone_init,注册cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers=ngx_http_limit_zone_handler;
  8. ngx_http_limit_req_module模块的钩子是ngx_http_limit_req_init,注册cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers=ngx_http_limit_req_handler;
  9. ngx_http_rewrite_module模块的钩子是ngx_http_rewrite_init,注册cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].handlers=ngx_http_rewrite_handler,还有cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers=ngx_http_rewrite_handler;
  10. ngx_http_write_filter_module模块的钩子是ngx_http_write_filter_init,注册ngx_http_top_body_filter = ngx_http_write_filter;
  11. ngx_http_header_filter_module模块的钩子是ngx_http_header_filter_init,注册ngx_http_top_header_filter = ngx_http_header_filter;
  12. ngx_http_chunked_filter_module模块的钩子是ngx_http_chunked_filter_init,函数体里的语句ngx_http_next_header_filter = ngx_http_top_header_filter表明越晚注册的钩子越先调用,ngx_http_next_body_filter = ngx_http_top_body_filter也是同理。注册ngx_http_top_header_filter = ngx_http_chunked_header_filter,ngx_http_top_body_filter = ngx_http_chunked_body_filter;
  13. ngx_http_range_header_filter_module模块的钩子是ngx_http_range_header_filter_init,注册ngx_http_top_header_filter = ngx_http_range_header_filter;
  14. ngx_http_gzip_filter_module模块的钩子是ngx_http_gzip_filter_init,注册ngx_http_top_header_filter = ngx_http_gzip_header_filter,ngx_http_top_body_filter = ngx_http_gzip_body_filter;
  15. ngx_http_postpone_filter_module模块的钩子是ngx_http_postpone_filter_init,注册ngx_http_top_body_filter = ngx_http_postpone_filter;
  16. ngx_http_ssi_filter_module模块的钩子是ngx_http_ssi_filter_init,注册ngx_http_top_header_filter = ngx_http_ssi_header_filter,ngx_http_top_body_filter = ngx_http_ssi_body_filter;
  17. ngx_http_charset_filter_module模块的钩子是ngx_http_charset_postconfiguration,注册ngx_http_top_header_filter = ngx_http_charset_header_filter,ngx_http_top_body_filter = ngx_http_charset_body_filter;
  18. ngx_http_userid_filter_module模块的钩子是ngx_http_userid_init,注册ngx_http_top_header_filter = ngx_http_userid_filter;
  19. ngx_http_headers_filter_module模块的钩子是ngx_http_headers_filter_init,注册ngx_http_top_header_filter = ngx_http_headers_filter;
  20. ngx_http_copy_filter_module模块的钩子是ngx_http_copy_filter_init,注册ngx_http_top_body_filter = ngx_http_copy_filter;
  21. ngx_http_range_body_filter_module模块的钩子是ngx_http_range_body_filter_init,注册ngx_http_top_body_filter = ngx_http_range_body_filter;
  22. ngx_http_not_modified_filter_module模块的钩子是ngx_http_not_modified_filter_init,注册ngx_http_top_header_filter = ngx_http_not_modified_header_filter。

ngx_http_init_phase_handlers函数注册http模块各phase的checker,将前面postconfiguration钩子注册的handler一并移到ngx_http_phase_engine_t类型的phase_engine中,这是ngx_http_core_main_conf_t的成员,最后的结果就是phase_engine构建了一个checker和handler对应的数组。解释下各phase:

 

 

ngx_http_optimize_servers函数排序端口,将server_name存储在hash表里,最后调用ngx_http_init_listening,ngx_http_init_listening又调用了ngx_http_add_listening,ngx_http_add_listening注册了一个非常重要的函数-----ngx_listening_t结构的handler:ngx_http_init_connection,之后所有的http连接都由这个函数处理,最后还有一个handler:ls->log.handler = ngx_accept_log_error。

 

http模块的初始化分析完成,涉及的东西很多很杂很恼人。这一章主要是整理了大量的handler,方便以后的处理流程分析,并没有对具体的各函数做太多的实质性分析。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值