本文档的Copyleft归L.L所有,使用GPL发布,可以自由转载,转载时请务必以超链接形式标明文章原始出处,严禁用于任何商业用途。
email: [email protected]
来源: http://blog.csdn.net/ccdd14
开始进入ngx_http_core_run_phases函数,它循环调用各http phase的checker。
void ngx_http_core_run_phases(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_phase_handler_t *ph; ngx_http_core_main_conf_t *cmcf; cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); ph = cmcf->phase_engine.handlers; while (ph[r->phase_handler].checker) { rc = ph[r->phase_handler].checker(r, &ph[r->phase_handler]); if (rc == NGX_OK) { return; } } }
先看看,在默认配置下,且不设置try_files指令,注册的checker和handler分别如下:
// ph[0].checker = ngx_http_core_generic_phase; ph[0].handler = ngx_http_rewrite_handler; ph[1].checker = ngx_http_core_find_config_phase; ph[1].handler = NULL; ph[2].checker = ngx_http_core_generic_phase; ph[2].handler = ngx_http_rewrite_handler; ph[3].checker = ngx_http_core_post_rewrite_phase; ph[3].handler = NULL; ph[4].checker = ngx_http_core_generic_phase; ph[4].handler = ngx_http_limit_req_handler; ph[5].checker = ngx_http_core_generic_phase; ph[5].handler = ngx_http_limit_zone_handler; ph[6].checker = ngx_http_core_access_phase; ph[6].handler = ngx_http_access_handler; ph[7].checker = ngx_http_core_access_phase; ph[7].handler = ngx_http_auth_basic_handler; ph[8].checker = ngx_http_core_post_access_phase; ph[8].handler = NULL; ph[9].checker = ngx_http_core_content_phase; ph[9].handler = ngx_http_index_handler; ph[10].checker = ngx_http_core_content_phase; ph[10].handler = ngx_http_autoindex_handler; ph[11].checker = ngx_http_core_content_phase; ph[11].handler = ngx_http_static_handler; ph[12].checker = ngx_http_core_generic_phase; ph[12].handler = ngx_http_log_handler;
因为r->phase_handler==0,第一个调用的checker是ngx_http_core_generic_phase,handler是ngx_http_rewrite_handler,然后按下标顺序逐个调用。
ngx_http_core_generic_phase做的事就是调用相应的handler,ngx_http_rewrite_handler则是根据rewrite相关的指令对http请求进行处理。
ngx_http_core_find_config_phase则是根据location指令进行处理,ngx_http_core_find_location查找匹配的location。
ngx_http_core_post_rewrite_phase判断uri rewrite的次数,没有重写过,则进入下一个phase,这时是ph[4]=ngx_http_core_generic_phase。如果重写次数过多(超过11次),则调用ngx_http_finalize_request返回错误应答,如果重写次数没有达到阈值,则进入的phase为ngx_http_core_find_config_phase。
ngx_http_core_access_phase先判断是否为子请求,如果r != r->main,则为子请求。然后调用的对应的handler,第一个是ngx_http_access_handler处理ip的访问控制,查看配置是否允许该请求访问。第二个是ngx_http_auth_basic_handler,处理基于用户名和密码的访问控制。
ngx_http_core_post_access_phase查看是否有拒绝的请求,如果r->access_code != 0,则有非法的请求。
ngx_http_core_content_phase主要是调用对应的handler:
1. 首先调用的是ngx_http_index_handler,它打开index指令配置
的根文件:index.html。如果http request header的uri不以"/"结尾,返回NGX_DECLINED;否则在最后会调用
ngx_http_internal_redirect,这个函数是实现nginx的internal redirect的方式之一,在修改了request header后,又会重新调用
ngx_http_handler,重新进行http处理流程。
2. 接着调用ngx_http_autoindex_handler;
3. 最后调用ngx_http_static_handler,主要功能是设置response header和body。设置head_out,content_type之后,
ngx_http_send_header调用ngx_http_top_header_filter链:
ngx_int_t ngx_http_send_header(ngx_http_request_t *r) { if (r->err_status) { r->headers_out.status = r->err_status; r->headers_out.status_line.len = 0; } return ngx_http_top_header_filter(r); }
这条链的filter按调用顺序如下:
ngx_http_not_modified_header_filter ngx_http_headers_filter ngx_http_userid_filter ngx_http_charset_header_filter ngx_http_ssi_header_filter ngx_http_gzip_header_filter ngx_http_range_header_filter ngx_http_chunked_header_filter ngx_http_header_filter
ngx_http_header_filter最后会调用ngx_http_write_filter,关于这个函数的源码分析可以查看
http://www.mindpin.com/rss_items/1291,做的讲解还是比较详细的。
ngx_http_static_handler在最后调用ngx_http_output_filter,而ngx_http_output_filter则遍历ngx_http_top_body_filter,调用的filter如下:
ngx_http_range_body_filter ngx_http_copy_filter ngx_http_charset_body_filter ngx_http_ssi_body_filter ngx_http_postpone_filter ngx_http_gzip_body_filter ngx_http_chunked_body_filter ngx_http_write_filter
ngx_http_core_content_phase处理完所有的handler后,会调用ngx_http_finalize_request来结束整个http的处理流程。
OK,nginx的处理流程分析完成!