参考资料<深入理解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请求的更多相关文章

  1. Nginx如何处理一个请求

    看了下nginx的官方文档,其中nginx如何处理一个请求讲解的很好,现在贴出来分享下.Nginx首先选定由哪一个虚拟主机来处理请求.让我们从一个简单的配置(其中全部3个虚拟主机都在端口*:80上监听 ...

  2. Apache与Nginx对客户端请求的处理机制对比

    Apache与Nginx对客户端请求的处理机制对比 模块 大致为四个模块,核心模块.HTTP模块.邮件模块,以及第三方模块 核心模块主要包含两类功能的支持,一类是主体功能,包括进程管理,权限管理,错误 ...

  3. [转载]Nginx如何处理一个请求

    http://nginx.org/cn/docs/http/request_processing.html 对我的扫盲文章 基于名字的虚拟主机 Nginx首先选定由哪一个虚拟主机来处理请求.让我们从一 ...

  4. Nginx配置TCP请求转发

    Nginx配置TCP请求转发 1.TCP请求转发基于stream在1.9版本前,需要单独编译安装该组建: # 依赖服务 [root@baolin conf]#yum -y install pcre-d ...

  5. nginx学习笔记(7)Nginx如何处理一个请求---转载

    如何防止处理未定义主机名的请求基于域名和IP混合的虚拟主机一个简单PHP站点配置 基于名字的虚拟主机 Nginx首先选定由哪一个虚拟主机来处理请求.让我们从一个简单的配置(其中全部3个虚拟主机都在端口 ...

  6. 修改nginx对http请求数据大小限制

    1. 问题发现 在公司搭建了一个基于mindoc的wiki知识库,用nginx做的反向代理服务器,同事在使用过程中上传某个文件一直失败,于是看着看下mindoc自己的日志文件,发现都是类似于fastd ...

  7. 【Nginx】HTTP请求的11个处理阶段

    Nginx将一个HTTP请求分成多个阶段.以模块为单位进行处理.这样做的优点是使处理过程更加灵活.减少耦合度.HTTP框架将处理分成了11个阶段,各个阶段能够包括随意多个HTTP模块并以流水线的方式处 ...

  8. Nginx 如何处理一个请求

    基于名字的虚拟主机 Nginx首先选定由哪一个虚拟主机来处理请求.让我们从一个简单的配置(其中全部3个虚拟主机都在端口*:80上监听)开始: server { listen 80; server_na ...

  9. nginx 跨域请求访问

    1.nginx跨域请求访问 location ~ .*\.(htm|html)$ { add_header Access-Control-Allow-Origin(请求域名) *(所有域名) http ...

  10. 万字长文!一次性弄懂 Nginx 处理 HTTP 请求的 11 个阶段

    Nginx 处理一个 HTTP 请求的全过程 前面给大家讲了 Nginx 是如何处理 HTTP请求头部的,接下来就到了真正处理 HTTP 请求的阶段了.先看下面这张图,这张图是 Nginx 处理 HT ...

随机推荐

  1. linux系统查看主机序列号

    #dmidecode -t 1 System Information        Manufacturer: IBM        Product Name: System x3650 M3 -[7 ...

  2. spring JPA写法一种

    第一次用,搞了半天,终于知道了大概. 基于ORM的JPA还是蛮好用的, 这次是实现一个MANGODB的日志存储和检索. PRISM用的. repository的写法: package paic.sto ...

  3. cdq分治浅谈

    $cdq$分治浅谈 1.分治思想 分治实际上是一种思想,这种思想就是将一个大问题划分成为一些小问题,并且这些小问题与这个大问题在某中意义上是等价的. 2.普通分治与$cdq$分治的区别 普通分治与$c ...

  4. bzoj3225 [Sdoi2008]立方体覆盖——扫描线

    3225: [Sdoi2008]立方体覆盖 Description A君近日为准备省队选拔,特意进行了数据结构的专项训练.训练过程中就遇到了“矩形面积并”这道经典问题,即:给出N个各边与坐标轴平行(垂 ...

  5. (寒假集训)Mooo Moo (完全背包)

    Mooo Moo 时间限制: 1 Sec  内存限制: 64 MB提交: 5  解决: 4[提交][状态][讨论版] 题目描述 Farmer John has completely forgotten ...

  6. [POI2014]Solar Panels

    题目大意: $T(T\le1000)$组询问,每次给出$A,B,C,D(A,B,C,D\le10^9)$,求满足$A\le x\le B,C\le y\le D$的最大的$\gcd(x,y)$. 思路 ...

  7. Unity3d之MonoBehavior的各个函数的执行顺序,回调,顺序,次数等

    Update 当MonoBehaviour启用时,其Update在每一帧被调用.仅调用一次(每帧) LateUpdate 当Behaviour启用时,  每帧调用一次: FixedUpdate 当Mo ...

  8. @selector和SEL

    遇到selector发现不是很明白,网上搜到的零零星星的介绍也不成体系,索性自己翻译一下,加深一下印象.原文来自官方API文档下的Selectors. Selectors 在OC中,selector有 ...

  9. 线程同步-CountDownLatch

    应用场景: 有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以继续往下执行. 假如我们这个想要继续往下执行的任务调用一个CountDownLatch对象的await()方法,其他的任务执行 ...

  10. oracle 博客精选

    http://mp.sohu.com/profile?xpt=b3JhbmV3c0Bzb2h1LmNvbQ==