【Nginx】HTTP请求的11个处理阶段
2014-06-14 21:41
666 查看
Nginx将一个HTTP请求分成多个阶段,以模块为单位进行处理。这样做的好处是使处理过程更加灵活、降低耦合度。HTTP框架将处理分成了11个阶段,各个阶段可以包含任意多个HTTP模块并以流水线的方式处理请求。这11个HTTP阶段如下所示:
以上11个阶段中,HTTP无法介入的阶段有4个:
NGX_HTTP_FIND_CONFIG_PHASE
NGX_HTTP_POST_REWRITE_PHASE
NGX_HTTP_POST_ACCESS_PHASE
NGX_HTTP_TRY_FILES_PHASE
剩余的7个阶段,HTTP模块均能介入,每个阶段可介入模块的个数也是没有限制的,多个HTTP模块可同时介入同一阶段并作用于同一请求。
下面是关于阶段的一些定义:
ngx_http_phase_handler_t结构体表示处理阶段中的一个处理方法。当解析完http{}块配置项后,会产生一个由ngx_http_phase_handler_t组成的数组handlers,被放在了ngx_http_phase_engine_t结构体中:
handlers指向了这个数组的起始地址。这个数组是所有HTTP模块都能合作处理用户请求的关键,一个用户请求就是被这个数组中的ngx_http_handler_pt方法依次处理。
ngx_http_phase_engine_t结构体又被保存在ngx_http_core_main_conf_t全局结构体(由ngx_http_core_module模块的ngx_http_core_create_main_conf方法创建)中:
在HTTP框架初始化过程中,任何HTTP模块定义了处理请求的方法ngx_http_handler_pt后,都可以调用自己的接口ngx_http_module_t中的postconfiguration函数将该方法添加到phase_engine中,也就是添加到ngx_http_core_main_conf_t.phase_engine.handlers数组中。当一个HTTP请求到达时,Nginx会调用某阶段的某个ngx_http_handler_pt指向的方法处理请求。介入所有11个阶段均可以使用上述方法。除此之外,介入NGX_HTTP_CONTENT_PHASE阶段还可以使用另外一种方法:把希望处理请求的ngx_http_handler_pt方法设置到location配置块相关的ngx_http_loc_conf_t结构体的handler指针中,如下所示:
如上例所示,它的好处在于:ngx_http_mytest_handler方法只会处理和该location的URI相匹配的请求,不会处理其它请求。所以,应该根据ngx_http_handler_pt处理方法是处理所有HTTP请求还是处理特定的某个请求,使用不同的方法将ngx_http_handler_pt介入到NGX_HTTP_CONTENT_PHASE阶段。
参考:
《深入理解Nginx》 P372-P382.
typedef enum { NGX_HTTP_POST_READ_PHASE = 0, // 接收到完整的HTTP头部后处理的阶段 NGX_HTTP_SERVER_REWRITE_PHASE, // URI与location匹配前,修改URI的阶段,用于重定向 NGX_HTTP_FIND_CONFIG_PHASE, // 根据URI寻找匹配的location块配置项 NGX_HTTP_REWRITE_PHASE, // 上一阶段找到location块后再修改URI NGX_HTTP_POST_REWRITE_PHASE, // 防止重写URL后导致的死循环 NGX_HTTP_PREACCESS_PHASE, // 下一阶段之前的准备 NGX_HTTP_ACCESS_PHASE, // 让HTTP模块判断是否允许这个请求进入Nginx服务器 NGX_HTTP_POST_ACCESS_PHASE, // 向用户发送拒绝服务的错误码,用来响应上一阶段的拒绝 NGX_HTTP_TRY_FILES_PHASE, // 为访问静态文件资源而设置 NGX_HTTP_CONTENT_PHASE, // 处理HTTP请求内容的阶段,大部分HTTP模块介入这个阶段 NGX_HTTP_LOG_PHASE // 处理完请求后的日志记录阶段 } ngx_http_phases;
以上11个阶段中,HTTP无法介入的阶段有4个:
NGX_HTTP_FIND_CONFIG_PHASE
NGX_HTTP_POST_REWRITE_PHASE
NGX_HTTP_POST_ACCESS_PHASE
NGX_HTTP_TRY_FILES_PHASE
剩余的7个阶段,HTTP模块均能介入,每个阶段可介入模块的个数也是没有限制的,多个HTTP模块可同时介入同一阶段并作用于同一请求。
下面是关于阶段的一些定义:
typedef struct ngx_http_phase_handler_s ngx_http_phase_handler_t; typedef ngx_int_t (*ngx_http_phase_handler_pt)(ngx_http_request_t *r, ngx_http_phase_handler_t *ph); typedef ngx_int_t (*ngx_http_handler_pt)(ngx_http_request_t *r); struct ngx_http_phase_handler_s { ngx_http_phase_handler_pt checker; // 由HTTP框架定义和调用,此函数又调用下方的handler方法 ngx_http_handler_pt handler; // HTTP模块通过实现这个方法介入某个阶段 ngx_uint_t next; // 下一个阶段的序号 };
ngx_http_phase_handler_t结构体表示处理阶段中的一个处理方法。当解析完http{}块配置项后,会产生一个由ngx_http_phase_handler_t组成的数组handlers,被放在了ngx_http_phase_engine_t结构体中:
typedef struct { ngx_http_phase_handler_t *handlers; // 一个请求可能经历的所有ngx_http_handler_pt处理方法 ngx_uint_t server_rewrite_index; ngx_uint_t location_rewrite_index; } ngx_http_phase_engine_t;
handlers指向了这个数组的起始地址。这个数组是所有HTTP模块都能合作处理用户请求的关键,一个用户请求就是被这个数组中的ngx_http_handler_pt方法依次处理。
ngx_http_phase_engine_t结构体又被保存在ngx_http_core_main_conf_t全局结构体(由ngx_http_core_module模块的ngx_http_core_create_main_conf方法创建)中:
typedef struct { .... ngx_http_phase_engine_t phase_engine; /* 保存处理HTTP请求的各个阶段 */ .... } ngx_http_core_main_conf_t;
在HTTP框架初始化过程中,任何HTTP模块定义了处理请求的方法ngx_http_handler_pt后,都可以调用自己的接口ngx_http_module_t中的postconfiguration函数将该方法添加到phase_engine中,也就是添加到ngx_http_core_main_conf_t.phase_engine.handlers数组中。当一个HTTP请求到达时,Nginx会调用某阶段的某个ngx_http_handler_pt指向的方法处理请求。介入所有11个阶段均可以使用上述方法。除此之外,介入NGX_HTTP_CONTENT_PHASE阶段还可以使用另外一种方法:把希望处理请求的ngx_http_handler_pt方法设置到location配置块相关的ngx_http_loc_conf_t结构体的handler指针中,如下所示:
static char* ngx_http_mytest(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_core_loc_conf_t *clcf; // 找到mytest配置项所属的配置块 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); // 设置处理请求的方法,HTTP框架在处理用户请求进行到NGX_HTTP_CONTENT_PHASE阶段时 // 如果主机域名、URI和mytest模块所在配置块名称相同,就会调用函数ngx_http_mytest_handler clcf->handler = ngx_http_mytest_handler; return NGX_CONF_OK; }
如上例所示,它的好处在于:ngx_http_mytest_handler方法只会处理和该location的URI相匹配的请求,不会处理其它请求。所以,应该根据ngx_http_handler_pt处理方法是处理所有HTTP请求还是处理特定的某个请求,使用不同的方法将ngx_http_handler_pt介入到NGX_HTTP_CONTENT_PHASE阶段。
参考:
《深入理解Nginx》 P372-P382.
相关文章推荐
- NGINX中HTTP请求的11个处理阶段
- 《深入理解Nginx》笔记之 HTTP请求的11个处理阶段
- Nginx处理请求的11个阶段(agentzh的Nginx 教程学习记录)
- 文章13:Nginx多阶段处理HTTP请求
- Nginx多阶段处理HTTP请求
- nginx 11个处理阶段 && nginx lua 8个处理阶段
- Nginx源码剖析--HTTP请求的分阶段处理的初始化
- nginx处理http请求流程
- nginx做反向代理处理http请求的过程
- Nginx的HTTP请求处理
- nginx的多阶段请求处理
- Nginx基础. HTTP多阶段处理大致分析
- 文章18 :Nginx中http请求的处理过程
- Nginx 请求处理阶段
- nginx一般的http请求建立处理,发送函数调用,以及各个phase的状态(等完善)
- nginx的多阶段请求处理
- Nginx源码分析 - 实战篇 - 编写一个挂载到阶段处理的模块
- Nginx处理HTTP请求的路由过程
- nginx作反向代理时的HTTP请求处理全过程解释
- nginx源码分析——http多阶段处理