内容简介:微信公众号:关注可了解更多的关注公众号,有趣有内涵的文章第一时间送达!请关注个人博客,戳这里
微信公众号:关注可了解更多的 Nginx 知识。任何问题或建议,请公众号留言;
关注公众号,有趣有内涵的文章第一时间送达!
请关注个人博客,戳这里
解析完请求头部之后调用ngx_http_process_request()函数
// 进入http的11个阶段处理
static void ngx_http_process_request(ngx_http_request_t *r)
{
ngx_connection_t *c;
c = r->connection;
if (r->plain_http) {
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent plain HTTP request to HTTPS port");
ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS);
return;
}
if (c->read->timer_set) {
ngx_del_timer(c->read);
}
c->read->handler = ngx_http_request_handler;
c->write->handler = ngx_http_request_handler;
r->read_event_handler = ngx_http_block_reading;
ngx_http_handler(r);
ngx_http_run_posted_requests(c);
}
复制代码
这个函数是在解析完 http 请求头之后调用的,我们分析一下他的功能:
1、删除定时器,因为 http 的头部已经解析完了,要进入 http 处理阶段了,所以可以删除原先的定时器了。
2、将 connection 的读写事件回调函数都设置为 ngx_http_request_handler 。代码如下:
当 epoll_wait() 监控到当前 connection 上发生了读写事件,就会调用 ngx_http_request_handler 函数,而这个函数根据读写事件的类型分别调用 http 连接的 read_event_handler 和 write_event_handler() 函数,其实不明白这里为什么要这么做。 然后调用 ngx_http_run_posted_requests() 函数处理子请求。也就是说,每当连接上面有读写事件发生的时候都会调用 ngx_http_run_posted_requests 来处理子请求。
static void ngx_http_request_handler(ngx_event_t *ev)
{
ngx_connection_t *c;
ngx_http_request_t *r;
ngx_http_log_ctx_t *ctx;
c = ev->data;
r = c->data;
ctx = c->log->data;
ctx->current_request = r;
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http run request: \"%V?%V\"", &r->uri, &r->args);
if (ev->write) {
r->write_event_handler(r);
} else {
r->read_event_handler(r);
}
ngx_http_run_posted_requests(c);
}
3、调用ngx_http_handler()函数
void
ngx_http_handler(ngx_http_request_t *r)
{
ngx_http_core_main_conf_t *cmcf;
r->connection->log->action = NULL;
r->connection->unexpected_eof = 0;
if (!r->internal) {
switch (r->headers_in.connection_type) {
case 0:
r->keepalive = (r->http_version > NGX_HTTP_VERSION_10);
break;
case NGX_HTTP_CONNECTION_CLOSE:
r->keepalive = 0;
break;
case NGX_HTTP_CONNECTION_KEEP_ALIVE:
r->keepalive = 1;
break;
}
r->lingering_close = (r->headers_in.content_length_n > 0);
r->phase_handler = 0;
} else {
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
r->phase_handler = cmcf->phase_engine.server_rewrite_index;
}
r->valid_location = 1;
r->write_event_handler = ngx_http_core_run_phases;
ngx_http_core_run_phases(r);
}
复制代码
这个函数的主要作用就是将 http 连接的 write_event_handler 设置为 ngx_http_core_run_phases 函数,然后调用 ngx_http_core_run_phases 函数,这个函数就是进入 nginx 的11个处理阶段。
4、调用 ngx_http_run_posted_requests 函数处理子请求。
综上所述,当 epoll_wait() 监控到 connection 上面有读写事件的时候会调用 ngx_http_core_run_phase() 函数进行11个阶段的处理。
ngx_http_core_run_phases() 的过程中,如果某一个处理阶段的
checker 函数返回了
NGX_OK ,那么从代码中可以看到,就会推出
ngx_http_core_run_phases() 函数,这个时候
nginx 的控制权就返回给了
epoll 模块,只能等待发生下一个事件的时候继续调用
ngx_http_core_run_phase()
进行处理。
// nginx的核心处理函数
void ngx_http_core_run_phases(ngx_http_request_t *r)
{
ngx_int_t rc;
ngx_http_phase_handler_t *ph;
ngx_http_core_main_conf_t *cmcf;
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
ph = cmcf->phase_engine.handlers;
while (ph[r->phase_handler].checker) {
rc = ph[r->phase_handler].checker(r, &ph[r->phase_handler]);
if (rc == NGX_OK) {
return;
}
}
}
复制代码
总结一下这个流程:
喜欢本文的朋友们,欢迎长按下图关注订阅号郑尔多斯,更多精彩内容第一时间送达
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 金色观察丨以太坊2.0从“零阶段”到“一阶段”比想象中简单?
- 服务端指南 服务端概述 | 微服务架构概述
- 技术人员发展四阶段
- 软件需求阶段—质量全面管控
- Nginx执行阶段详细解析
- 数据中台建设成功的三个阶段
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Head First Web Design
Ethan Watrall、Jeff Siarto / O’Reilly Media, Inc. / 2009-01-02 / USD 49.99
Want to know how to make your pages look beautiful, communicate your message effectively, guide visitors through your website with ease, and get everything approved by the accessibility and usability ......一起来看看 《Head First Web Design》 这本书的介绍吧!