参考资料<深入理解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. JavaEE中Filter实现用户登录拦截

    实现思路是编写过滤器,如果用户登录之后session中会存一个user.如果未登录就为null,就可以通过过滤器将用户重定向到登陆页面,让用户进行登陆,当然过滤器得判断用户访问的如果是登陆请求需要放行 ...

  2. 除了IE浏览器,其他浏览器都联不上网怎么办~转载百度经验

    百度师傅最快的到家服务,最优质的电脑清灰 百度经验:jingyan.baidu.com 有个网友遇到一个非常奇怪的上网问题,刚才始,发现QQ不能登录,后来接着发现火狐浏览器也打不开网页,刚开始,以为只 ...

  3. 跨平台的EVENT事件 windows linux

    #ifndef _HIK_EVENT_H_ #define _HIK_EVENT_H_ #ifdef _MSC_VER #include <Windows.h> #define hik_e ...

  4. js5秒后自动关闭本页面及5秒钟后自动跳转指定页面的方法

    5秒钟后自动关闭 <!DOCTYPE HTML> <html> <head> <title>倒计时自动关闭/跳转页面</title> < ...

  5. Openstack ceilometer

    https://www.cnblogs.com/liguangsunls/p/6879879.html

  6. android 效果

    1.TextView 有边界的水波效果: android:background="?android:attr/selectableItemBackground" 无边界的水波效果: ...

  7. Python与数据库[2] -> 关系对象映射/ORM[3] -> sqlalchemy 的声明层 ORM 访问方式

    sqlalchemy的声明层ORM访问方式 sqlalchemy中可以利用声明层进行表格类的建立,并利用ORM对象进行数据库的操作及访问,另一种方式为显式的 ORM 访问方式. 主要的建立步骤包括: ...

  8. Linq 连接运算符:Concat,Union

    //Concat()方法附加两个相同类型的序列,并返回一个新序列(集合)IList<string> strList = new List<string>() { "O ...

  9. Go VUE --- vuejs在服务器部署?

    感觉好多人把最基本的都忘了 还npm run dev 还守护进程,用守护进程也应该你自己用nodejs实现一个web静态服务器而不是去守护npm run dev 楼主问的既然是布署,哪默认就应该是生产 ...

  10. 关于Android导入开源项目:Error:Unable to load class 'org.gradle.api.publication.maven.internal.DefaultMavenFa

    在导入开源项目时,有可能会要求需要maven插件,并报出一下错误: 对于没有安装maven插件的开发者来说,要去下载一个maven插件也许不困难,但是,有时候可能会像我一样懒,不去下载插件,那么我们可 ...