Nginx:处理HTTP请求
参考资料<深入理解Nginx>(陶辉)
处理HTTP请求
接着上一次的内容,本次将说明HTTP框架是如何召集负责具体功能的各HTTP模块合作处理请求的。
在http://www.cnblogs.com/runnyu/p/4918135.html的最后是通过ngx_http_process_request方法开始处理请求的,该方法流程如下图
2.设置读、写事件的回调方法为ngx_http_request_handler方法,请求的后续处理都是通过ngx_http_request_handler方法进行的。
6.设置ngx_http_request_t结构体的write_event_handler成员为ngx_http_core_run_phases方法。该方法可能会被多次调度来完成HTTP请求的处理。
7.调用ngx_http_core_run_phases回调方法,该方法执行流程如下
ngx_http_request_t结构体中的phase_handler成员(处理流程的核心)将决定执行到哪一阶段,关于该成员跟其相关的数据结构可以查看http://www.cnblogs.com/runnyu/p/4910952.html。
该回调方法的源码如下
void ngx_http_core_run_phases(ngx_http_request_t *r)
{
ngx_int_t rc;
ngx_http_phase_handler_t *ph; cmcf=ngx_http_get_module_man_conf(r,ngx_http_core_module);
ph=cmcf->phase_engine.handlers; while(ph[phase_handler].checker){
rc=ph[r->phase_handler].checker(r,&ph[r->phase_hanlder]);
if(rc==NGX_OK){
return;
}
}
}
只有当相应的checker方法返回NGX_OK时才将控制权交还给Nginx的事件模块,否则将继续执行(checker方法中会修改phase_handler成员以向下执行)。
当这个请求上对应的事件再次触发时,HTTP框架将回调ngx_http_request_handler方法开始处理请求(上面已经设置了该方法为其读、写事件的回调方法)。
下图是ngx_http_request_handler方法的流程
2.如果当前事件可写,将调用ngx_http_reqeust_t结构体中的write_event_handler方法。该方法在上面已经设置为ngx_http_core_run_phases,可见该方法会被多次调用。
Checker方法
checker方法是HTTP框架定义的,每一个HTTP处理阶段对应着相应着一个checker方法(有的阶段的checker方法一样),handler方法只有在checker方法中调用。
checker方法的主要任务在于,根据phase_handler执行某个HTTP模块实现的回调方法,并根据方法的返回值决定:
1.当前阶段是否已经结束
2.下次要执行的回调方法是哪一个
3.是立刻执行下一个回调方法还是先把控制权交还给epoll
下面介绍HTTP框架中其中两个checker方法的介绍
ngx_http_core_generic_phase
在前面的http://www.cnblogs.com/runnyu/p/4910952.html下面有该方法的介绍,下面只给出该方法的流程图
可见,checker方法主要是根据handler方法的返回值来改变phase_handler的值以用来控制handler方法的执行顺序的。
ngx_http_core_content_phase
ngx_http_core_content_phase是NGX_HTTP_CONTENT_PHASE阶段的checker方法。是我们开发HTTP模块时最常用的一个阶段。
其余10个阶段中各HTTP模块的handler方法都是放在全局ngx_http_core_main_conf_t结构体中,而该阶段的handler方法则可以放在ngx_http_core_conf_t结构体中,这就是按需挂载的基础
typedef struct ngx_http_core_loc_conf_s ngx_http_core_loc_conf_t
struct ngx_http_core_loc_conf_s {
...
ngx_http_handler_pt handler;
...
}
在我们最初的开发的HTTP模块中:http://www.cnblogs.com/runnyu/p/4871866.html
当检测到mytest配置项后,调用ngx_http_mytest方法将上面ngx_http_core_loc_conf_t的handler成员设置为自己的handler函数,实现了按需挂载。
事实上,在NGX_HTTP_FIND_CONFIG_PHASE阶段就会把ngx_http_request_t结构体的content_handler成员设置为匹配请求URI的location下的ngx_http_core_loc_conf_t结构体的handler成员。
下面是该checker方法的流程图,可以看出是如何实现按需挂载的
处理HTTP包体
在接收完HTTP头部后,就开始调用各HTTP模块处理请求了,然后由HTTP模块决定如何处理包体(handler函数)。
1.接收包体
ngx_int_t ngx_http_read_client_request_body(ngx_http_request *r,ngx_http_client_body_handler_pt post_handler);
typedef void (*ngx_http_client_body_handler_pt) (ngx_http_request_t *r);
接收到的包体保存在ngx_http_reqeust_body_t中,一般调用该函数的handler函数会接着返回NGX_DONE。
在完成接收动作之后,会调用post_handler函数继续处理请求。
2.放弃接收包体(Nginx必须接收包体,但不做处理)
ngx_int ngx_http_discard_reqeust_body(ngx_http_request_t *r);
调用该函数的handler函数继续处理请求,Nginx会异步地接收跟丢弃包体。
发送HTTP响应
显然,发送HTTP响应也是在handler函数中调用的。
1.发送响应头
ngx_int_t ngx_http_send_header(ngx_http_request_t *r);
该方法会异步地根据ngx_http_reqeust_t中的header_out成员将HTTP头部发送给客户端(经过各个过滤模块)。
2.发送响应体
ngx_int_t ngx_http_output_filter(ngx_http_request_t *r,ngx_chain_t *in);
该方法会异步地根据参数in将HTTP响应体发送给客户端(经过各个过滤模块)。
Nginx:处理HTTP请求的更多相关文章
- Nginx如何处理一个请求
看了下nginx的官方文档,其中nginx如何处理一个请求讲解的很好,现在贴出来分享下.Nginx首先选定由哪一个虚拟主机来处理请求.让我们从一个简单的配置(其中全部3个虚拟主机都在端口*:80上监听 ...
- Apache与Nginx对客户端请求的处理机制对比
Apache与Nginx对客户端请求的处理机制对比 模块 大致为四个模块,核心模块.HTTP模块.邮件模块,以及第三方模块 核心模块主要包含两类功能的支持,一类是主体功能,包括进程管理,权限管理,错误 ...
- [转载]Nginx如何处理一个请求
http://nginx.org/cn/docs/http/request_processing.html 对我的扫盲文章 基于名字的虚拟主机 Nginx首先选定由哪一个虚拟主机来处理请求.让我们从一 ...
- Nginx配置TCP请求转发
Nginx配置TCP请求转发 1.TCP请求转发基于stream在1.9版本前,需要单独编译安装该组建: # 依赖服务 [root@baolin conf]#yum -y install pcre-d ...
- nginx学习笔记(7)Nginx如何处理一个请求---转载
如何防止处理未定义主机名的请求基于域名和IP混合的虚拟主机一个简单PHP站点配置 基于名字的虚拟主机 Nginx首先选定由哪一个虚拟主机来处理请求.让我们从一个简单的配置(其中全部3个虚拟主机都在端口 ...
- 修改nginx对http请求数据大小限制
1. 问题发现 在公司搭建了一个基于mindoc的wiki知识库,用nginx做的反向代理服务器,同事在使用过程中上传某个文件一直失败,于是看着看下mindoc自己的日志文件,发现都是类似于fastd ...
- 【Nginx】HTTP请求的11个处理阶段
Nginx将一个HTTP请求分成多个阶段.以模块为单位进行处理.这样做的优点是使处理过程更加灵活.减少耦合度.HTTP框架将处理分成了11个阶段,各个阶段能够包括随意多个HTTP模块并以流水线的方式处 ...
- Nginx 如何处理一个请求
基于名字的虚拟主机 Nginx首先选定由哪一个虚拟主机来处理请求.让我们从一个简单的配置(其中全部3个虚拟主机都在端口*:80上监听)开始: server { listen 80; server_na ...
- nginx 跨域请求访问
1.nginx跨域请求访问 location ~ .*\.(htm|html)$ { add_header Access-Control-Allow-Origin(请求域名) *(所有域名) http ...
- 万字长文!一次性弄懂 Nginx 处理 HTTP 请求的 11 个阶段
Nginx 处理一个 HTTP 请求的全过程 前面给大家讲了 Nginx 是如何处理 HTTP请求头部的,接下来就到了真正处理 HTTP 请求的阶段了.先看下面这张图,这张图是 Nginx 处理 HT ...
随机推荐
- Object和Thread自带的原生方法
Object类: 1) clone():创建并返回此对象的一个副本. 2) equals(obj):指示其对象是否与此对象“相等”. 3) finalize():当垃圾回收器确定不存在对该对象的更多引 ...
- 引进js文件运行在浏览器上调试报文件找不到
原因是jsp文件的路径和js文件不在同一目录下,用"../"将它们的路径配置在同一路径下或者在路径前面加上"<%= request.getContextPath() ...
- flask框架下的jinja2模板引擎(3)(模板继承与可以在模板使用的变量、方法)
flask 框架下的jinja2模块引擎(1):https://www.cnblogs.com/chichung/p/9774556.html flask 框架下的jinja2模块引擎(2):http ...
- org.hibernate.HibernateException: Unable to get the default Bean Validation factor
org.hibernate.HibernateException: Unable to get the default Bean Validation factor这个异常需要在hibernate.c ...
- oracle修改字段类型由varchar2修改为clob类型
oracle修改字段类型由varchar2修改为clob类型 http://blog.sina.com.cn/s/blog_9d12d07f0102vxis.html
- window 10 64bit 安装nodejs v7.0.5 + npm v4.1.2 + Express 4.x及搭建web开发环境
1.先安装nodejs.npm. 2.然后安装Express (4.0之后需要安装express-generator) npm install -g express npm install -g ex ...
- ESXI和vSphere的安装配置-实现一台电脑硬件虚拟化为两台
本篇文章包含以下几个部分: 1EXSI软件和vSphere软件的安装 2在vSphere上安装虚拟系统 3对虚拟系统通过配置实现硬件虚拟化,实现硬件直通 1.EXSI安装 通过网上下载EXSI ISO ...
- 洛谷—— P3908 异或之和
https://www.luogu.org/problemnew/show/P3908 题目描述 求1 \bigoplus 2 \bigoplus\cdots\bigoplus N1⨁2⨁⋯⨁N 的值 ...
- 洛谷——P3395 路障
P3395 路障 题目背景 此题约为NOIP提高组Day1T1难度. 题目描述 B君站在一个n*n的棋盘上.最开始,B君站在(1,1)这个点,他要走到(n,n)这个点. B君每秒可以向上下左右的某个方 ...
- 洛谷 P3636 曲面
题目背景 xht喜欢研究数学函数,他特别喜欢反比例函数. 题目描述 我们知道,反比例函数xy=a的图象是双曲线. xht于是想:把它推广到三维是什么样的呢? 定义曲面C(k)为方程xyz=k所确定的曲 ...