在处理完http的头部信息后  然后在 处理request-body信息ngx_http_process_request--------

-----------ngx_http_process_request_headers(ngx_http_process_request_header)头部行解析完毕后调用函数ngx_http_process_request_header

ngx_http_process_request:设置read和write的回调函数ngx_http_request_handler,ngx_http_request_handler通过状态机来判断是读事件还是写事件。

void
ngx_http_process_request(ngx_http_request_t *r)
{
ngx_connection_t *c; c = r->connection; #if (NGX_HTTP_SSL) -----------------------
#endif
/*
由于现在已经开始准备调用各HTTP模块处理请求了,因此不再存在接收HTTP请求超时的问题????,那就需要从定时器中把当前连接的读事件移除了。
检查读事件对应的timer_set标志位,力1时表示读事件已经添加到定时器中了,这时需要调用ngx_del_timer从定时器中移除读事件;
*/
if (c->read->timer_set) {//ngx_http_read_request_header中读取不到数据的时候返回NGX_AGIN,会添加定时器和读事件表示继续等待客户端数据到来
ngx_del_timer(c->read, NGX_FUNC_LINE);
} #if (NGX_STAT_STUB)
(void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
r->stat_reading = 0;
(void) ngx_atomic_fetch_add(ngx_stat_writing, 1);
r->stat_writing = 1;
#endif /*
从现在开始不会再需要接收HTTP请求行或者头部,所以需要重新设置当前连接读/写事件的回调方法。在这一步骤中,将同时把读事件、写事件的回调
方法都设置为ngx_http_request_handler方法,请求的后续处理都是通过ngx_http_request_handler方法进行的。
*/
c->read->handler = ngx_http_request_handler; //由读写事件触发ngx_http_request_handler //由epoll读事件在ngx_epoll_process_events触发
c->write->handler = ngx_http_request_handler; //由epoll写事件在ngx_epoll_process_events触发 /*
设置ngx_http_request_t结构体的read_event_handler方法gx_http_block_reading。当再次有读事件到来时,将会调用ngx_http_block_reading方法
处理请求。而这里将它设置为ngx_http_block_reading方法,这个方法可认为不做任何事,它的意义在于,目前已经开始处理HTTP请求,除非某个HTTP模块重新
设置了read_event_handler方法,否则任何读事件都将得不到处理,也可似认为读事件被阻 塞了。
*/
r->read_event_handler = ngx_http_block_reading; //表示暂时不要读取客户端请求 /* ngx_http_process_request和ngx_http_request_handler这两个方法的共通之处在于,它们都会先按阶段调用各个HTTP模块处理请求,再处理post请求 */
ngx_http_handler(r); //这里面会执行ngx_http_core_run_phases,执行11个阶段 /*
HTTP框架无论是调用ngx_http_process_request方法(首次从业务上处理请求)还是ngx_http_request_handler方法(TCP连接上后续的事件触发时)处理
请求,最后都有一个步骤,就是调用ngx_http_run_posted_requests方法处理post请求 11个阶段执行完毕后,调用ngx_http_run_posted_requests方法执行post请求,这里一般都是对subrequest进行处理
*/
ngx_http_run_posted_requests(c); /* */
}

ngx_http_block_reading:del event at epoll

/*
把读事件从epoll中移除。只对epoll lt模式其作用它的意义在于,目前已经开始处理HTTP请求,除非某个HTTP模块重新设置了read_event_handler方法,
否则任何读事件都将得不到处理,也可似认为读事件被阻 塞了。 注意这里面会调用ngx_del_event,因此如果需要继续读取客户端请求内容,需要加上ngx_add_event,例如可以参考下ngx_http_discard_request_body
*/
void
ngx_http_block_reading(ngx_http_request_t *r)
{
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http reading blocked"); /* aio does not call this handler */ if ((ngx_event_flags & NGX_USE_LEVEL_EVENT)
&& r->connection->read->active)
{
if (ngx_del_event(r->connection->read, NGX_READ_EVENT, 0) != NGX_OK) {
ngx_http_close_request(r, 0);
}
}
}
  • ngx_http_request_handler

HTTP框架无论是调用ngx_http_process_request方法(首次从业务上处理请求)还是ngx_http_request_handler方法(TCP连接上后续的事件触发时)处理
请求,最后都有一个步骤,就是调用ngx_http_run_posted_requests方法处理post请求
*客户端事件处理handler一般(write(read)->handler)一般为ngx_http_request_handler, 和后端的to server handler一般(write(read)->handler)一般为ngx_http_upstream_handler
*/
static void
ngx_http_request_handler(ngx_event_t *ev)
{
ngx_connection_t *c;
ngx_http_request_t *r; /*
ngx_http_request_handler是HTTP请求上读/写事件的回调方法。在ngx_event_t结构体表示的事件中,data成员指向了这个事件对应的ngx_connection_t连接,
在HTTP框架的ngx_connection_t结构体中的data成员则指向了ngx_http_request_t结构体
*/
c = ev->data;
r = c->data; ngx_http_set_log_request(c->log, r); ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http run request(ev->write:%d): \"%V?%V\"", ev->write, &r->uri, &r->args); /*
检查这个事件的write可写标志,如果write标志为l,则调用ngx_http_request_t结构体中的write event- handler方法。注意,我们在ngx_http_handler
方法中已经将write_event_handler设置为ngx_http_core_run_phases方法,而一般我们开发的不太复杂的HTTP模块是不会重新设置write_event_handler方
法的,因此,一旦有可写事件时,就会继续按照流程执行ngx_http_core_run_phases方法,并继续按阶段调用各个HTTP模块实现的方法处理请求。 如果一个事件的读写标志同时为1时,仅write_event_handler方法会被调用,即可写事件的处理优先于可读事件(这正是Nginx高性能设计的体现,
优先处理可写事件可以尽快释放内存,尽量保持各HTTP模块少使用内存以提高并发能力)。因为服务器发送给客户端的报文长度一般比请求报文大很多
*/
//当ev为ngx_connection_t->write 默认write为1;当ev为ngx_connection_t->read 默认write为0
if (ev->write) { //说明ev是ngx_connection_t->write
r->write_event_handler(r); //ngx_http_core_run_phases } else {//说明ev是ngx_connection_t->read事件
r->read_event_handler(r);
} /*
HTTP框架无论是调用ngx_http_process_request方法(首次从业务上处理请求)还是ngx_http_request_handler方法(TCP连接上后续的事件触发时)处理
请求,最后都有一个步骤,就是调用ngx_http_run_posted_requests方法处理post请求
*/
/* ngx_http_process_request和ngx_http_request_handler这两个方法的共通之处在于,它们都会先按阶段调用各个HTTP模块处理请求,再处理post请求 ---
------主要用于处理subrequest 子请求
*/
ngx_http_run_posted_requests(c);
}

处理request信息的ngx_http_process_request的更多相关文章

  1. python 抓取request信息,各种cookie,user-agent类的信息,只调试到http可以抓取,https貌似不行。

    import pcap # 安装的是pypcap,本博客有安装方法,不过也比较乱,试试吧.import dpktimport socketimport datetime def sniffer(str ...

  2. ASP.NET Core 如何记录每次请求的Request信息 - sky 胡萝卜星星 - CSDN博客

    原文:ASP.NET Core 如何记录每次请求的Request信息 - sky 胡萝卜星星 - CSDN博客 版权声明:本文为starfd原创文章,转载请标明出处. https://blog.csd ...

  3. recess----2.Controller里面取用request信息

    事实上,第一个APP里面除了没有model,其它的都有用过了,但是需要单独拎出来看看清楚. Recess框架里面的controller就是一个典型的MVC框架的controller,它负责处理从浏览器 ...

  4. 获取当前TestStep发送的request信息

    在当前test step的Script Assertion里添加 // Get request url def requestURL = messageExchange.getEndpoint() / ...

  5. Springboot feign 传递request信息

    基础实现 requestInterceptor 实现类中添加信息 public class NativeFeignConf { @Bean public RequestInterceptor getR ...

  6. 多线程异步操作导致异步线程获取不到主线程的request信息

    org.springframework.web.context.request.RequestContextHolderorg.springframework.web.context.request. ...

  7. 【转】对Django框架架构和Request/Response处理流程的分析

    本文转载于疯狂的蚂蚁. 一. 处理过程的核心概念 如下图所示django的总览图,整体上把握以下django的组成: 核心在于中间件middleware,django所有的请求.返回都由中间件来完成. ...

  8. 【Django】django 处理request流程细节(转)

    首先发生的是一些和 Django 有关(前期准备)的其他事情,分别是: 如果是 Apache/mod_python 提供服务,request 由 mod_python 创建的 django.core. ...

  9. DotnetSpider (二) Downloader的设置 Request自定义数据字典

    本篇主要分享自定义Downloader和Request信息,实现自定义请求内容,及将自定义内容存储. ** 温馨提示:如需转载本文,请注明内容出处.**     本文连接:http://www.cnb ...

随机推荐

  1. 从源码的角度解析Mybatis的会话机制

    坐在我旁边的钟同学听说我精通Mybatis源码(我就想不通,是谁透漏了风声),就顺带问了我一个问题:在同一个方法中,Mybatis多次请求数据库,是否要创建多个SqlSession会话? 可能最近撸多 ...

  2. v-model数据绑定分析

    v-model数据绑定分析 v-model是Vue提供的指令,其主要作用是可以实现在表单<input>.<textarea>及<select>等元素以及组件上创建双 ...

  3. go 接口实现

    package main import ( "fmt" ) // 定义接口 type Beahavior interface { Run() string Eat(thing st ...

  4. xpath教程-逐层检索和全局检索 转

    逐层检索和全局检索 布啦豆 11203   本节主要介绍用xpath来描述html的层级关系 主要使用到的知识点如下: 单独的一个点 .,表示当前位置 两个点 ..,表示上一级父标签的位置 单独的一个 ...

  5. 【应用服务 App Service】Azure 应用服务测试网络访问其他域名及请求超时限制(4分钟 ≈ 230秒)

    测试App Service是否可以访问其他DNS 当应用服务(Azure App Service)创建完成后,想通过ping命令来查看是否可以访问其他站点或解析DNS,但是发现ping命令无法使用.这 ...

  6. 【API管理 APIM】APIM集成内部VNet后,自我访问出现(Unable to connect to the remote server)问题,而Remote Server正是APIM它自己

    问题描述 在使用APIM配置内部VNET后,如API-1正常配置访问后端服务器的一个接口,而API-2则是通过调用APIM中的API-1来作为backendUrl,会出现500错误. 经过测试,目前这 ...

  7. python的部分GUI模块简介tkinter、pyqt5(Qt Designer)

    笔者认为,这两个作为Python3较为常用且简单的GUI模块,是Python开发者所必须学习至少是了解的. 其中tkinter为Python3自带的GUI模块,而pyqt5则需要通过pip insta ...

  8. linux ssh自动输入密码,expect使用

    想搞一个使用ssh登录批量ip地址执行命令,自动输入密码的脚本,但是ssh不能使用标准输入来实现自动输入密码,于是了解到了expect这个可以交互的命令 是什么 查看使用man查看expect,是这么 ...

  9. IDEA出现Error Loading Project: Cannot load module xxx报错

    IDEA出现Error Loading Project: Cannot load module xxx报错,是因为IDEA不能找到模块xxx加载,应该是添加/新建了xxx模块,之后又删除了该模块,但没 ...

  10. windows下安装RabbitMq和常用命令

    ----RabbitMq安装-----windows下安装:(1)首先windows下安装好了erlang和rabbitmq.如下地址同时下载和安装:Erlang:http://www.erlang. ...