首页 > 代码库 > 【Nginx】HTTP请求的11个处理阶段
【Nginx】HTTP请求的11个处理阶段
Nginx将一个HTTP请求分成多个阶段,以模块为单位进行处理。这样做的好处是使处理过程更加灵活、降低耦合度。HTTP框架将处理分成了11个阶段,各个阶段以流水线的方式处理请求。这11个HTTP阶段如下所示:
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模块可同时介入同一阶段。
下面来看看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_handler_pt函数原型介入到某个阶段中来的。在处理到某个HTTP阶段时,HTTP框架会调用checker指向的函数,在这个函数中再调用各个HTTP模块的handler方法。
当解析完http{}块配置项后,根据配置文件产生的ngx_http_phase_handler_t阶段都会链入一个链表中:
typedef struct { ngx_http_phase_handler_t *handlers; // 一个请求可能经历的所有处理方法 ngx_uint_t server_rewrite_index; ngx_uint_t location_rewrite_index; } ngx_http_phase_engine_t;
上述结构体的ngx_http_phase_handler_t成员就是这个链表的表头,这是所有HTTP模块都能合作处理用户请求的关键。
ngx_http_phase_handler_t结构体又被保存在ngx_http_core_main_conf_t结构体(由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_module_t接口中的postconfiguration方法将自定义的方法添加到handler动态数组中。这样,这个自定义方法便加入到phase_engine->handlers链表中。
参考:
《深入理解Nginx》 P372-P376.
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。