参考资料<深入理解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用户态定时器的使用---19【转】

    转自:http://www.cnblogs.com/zxouxuewei/p/5095288.html 原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuew ...

  2. 【原创】Linux环境下的图形系统和AMD R600显卡编程(8)——AMD显卡DRM驱动初始化过程

    前面几个blog对DRM驱动.显卡的显存管理机制.中断机制都进行了一些描述,现在阅读AMD drm驱动的初始化过程应该会轻松许多. 下面是一AMD的开发人员编写的文章(先暂时放在这里,后续有时间再添加 ...

  3. Centos 6.3nginx安装

    1. 增加源: vi /etc/yum.repos.d/nginx.repo CentOS: [nginx] name=nginx repo baseurl=http://nginx.org/pack ...

  4. C# Log4Net使用示例

    using log4net; using log4net.Config; using System; using System.IO; namespace Three.Logging { /// &l ...

  5. 通过hover修改其他元素

    hover,我们都知道,是监听组件“悬停状态”的一个伪类. 我们一般通过hover来修改组件的背景什么的,很少涉及到太复杂的操作.也就是说我们一般只是对加了hover伪类的元素自身的样式进行改变,比如 ...

  6. 你不一定知道的、并没有什么卵用的一些python库

    1. delorean,用来处理时间的库 import datetime import pytz # 一般情况下,我们想表示时间的话 est = pytz.timezone("Asia/Sh ...

  7. C#模拟进行压力测试

    using System; using System.Diagnostics; using System.IO; using System.Net; using System.Text; using ...

  8. Ubuntu14.04安装配置LAMP环境(php5.6)

    sudo apt-get install python-software-properties sudo apt-get update sudo apt-get install vim sudo ap ...

  9. Ansible 删除多个文件或目录

    翻译和转载该网页内容 http://www.mydailytutorials.com/ansible-delete-multiple-files-directories-ansible/ 背景 ans ...

  10. java copy array

    13down voteaccepted Here's a java 1.4 compatible 1.5-liner: int[] array = { 1, 2, 3, 4, 5 }; int siz ...