src\http\ngx_http_request.c
void
ngx_http_process_request(ngx_http_request_t *r)
{
ngx_connection_t *c;
c = r->connection;
#if (NGX_HTTP_SSL)
if (r->http_connection->ssl) {
long rc;
X509 *cert;
const char *s;
ngx_http_ssl_srv_conf_t *sscf;
if (c->ssl == NULL) {
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;
}
sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
if (sscf->verify) {
rc = SSL_get_verify_result(c->ssl->connection);
if (rc != X509_V_OK
&& (sscf->verify != 3 || !ngx_ssl_verify_error_optional(rc)))
{
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client SSL certificate verify error: (%l:%s)",
rc, X509_verify_cert_error_string(rc));
ngx_ssl_remove_cached_session(c->ssl->session_ctx,
(SSL_get0_session(c->ssl->connection)));
ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR);
return;
}
if (sscf->verify == 1) {
cert = SSL_get_peer_certificate(c->ssl->connection);
if (cert == NULL) {
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent no required SSL certificate");
ngx_ssl_remove_cached_session(c->ssl->session_ctx,
(SSL_get0_session(c->ssl->connection)));
ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
return;
}
X509_free(cert);
}
if (ngx_ssl_ocsp_get_status(c, &s) != NGX_OK) {
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client SSL certificate verify error: %s", s);
ngx_ssl_remove_cached_session(c->ssl->session_ctx,
(SSL_get0_session(c->ssl->connection)));
ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR);
return;
}
}
}
#endif
if (c->read->timer_set) {
ngx_del_timer(c->read);
}
#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
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_process_request
是 Nginx 中处理 HTTP 请求的核心函数,主要完成以下工作:
-
SSL/TLS 验证(如果启用):
- 检查是否为 HTTPS 请求,若客户端发送明文 HTTP 到 HTTPS 端口则拒绝。
- 验证客户端证书(如果配置需要),包括证书有效性、是否提供证书(若必需)以及 OCSP 状态。
- 失败时返回相应的错误(如
NGX_HTTP_TO_HTTPS
、NGX_HTTPS_CERT_ERROR
)。
-
调整连接状态:
- 取消连接的读定时器(如果设置)。
- 更新统计信息(如读写状态计数,仅在启用统计模块时)。
-
设置事件处理器:
- 将连接的读写事件处理器设置为
ngx_http_request_handler
。 - 设置请求的读事件处理器为
ngx_http_block_reading
(阻止进一步读取)。
- 将连接的读写事件处理器设置为
-
转入请求处理:
- 调用
ngx_http_handler
进入请求处理的下阶段(如调用模块处理请求、生成响应等)。
- 调用
作用总结:完成请求的初始验证(尤其是 SSL),配置事件处理逻辑,并移交请求给 Nginx 的 HTTP 处理核心。
void
ngx_http_process_request(ngx_http_request_t *r)
{
- 返回类型:
void
,表示该函数不返回任何值。 - 参数:
ngx_http_request_t *r
:指向ngx_http_request_t
结构的指针,该结构存储了 HTTP 请求的所有相关信息(如请求头、连接信息、HTTP 方法等)。
if (r->http_connection->ssl) {
- 该条件判断 当前 HTTP 请求是否基于 SSL/TLS(即 HTTPS)。
- 如果
r->http_connection->ssl
为真,表示该请求是通过 HTTPS 加密传输的,需要进一步进行 SSL 验证(如证书检查、OCSP 校验等)。 - 如果为假,则跳过 SSL 相关处理,直接进入普通 HTTP 请求流程。
if (c->read->timer_set) {
ngx_del_timer(c->read);
}
- 检查读事件(
c->read
)是否设置了定时器(用于超时控制)。 - 如果已设置定时器,则删除它,防止后续处理被超时机制干扰。
在 HTTP 请求的初始阶段(如接收请求头),Nginx 可能设置了读超时定时器(例如 client_header_timeout
)。
一旦请求头接收完成并进入正式处理阶段(ngx_http_process_request
),就不再需要这个定时器,否则可能误触发超时关闭连接。
c->read->handler = ngx_http_request_handler;
c->write->handler = ngx_http_request_handler;
r->read_event_handler = ngx_http_block_reading;
- 将连接的 读事件(
c->read
) 和 写事件(c->write
) 的处理器统一设置为ngx_http_request_handler
。 - 这意味着:
- 当客户端发送数据(触发读事件)时,由
ngx_http_request_handler
处理。 - 当Nginx需要向客户端发送数据(触发写事件)时,同样由
ngx_http_request_handler
处理。
- 当客户端发送数据(触发读事件)时,由
r->read_event_handler = ngx_http_block_reading;
作用
- 将请求的 读事件处理器 设置为
ngx_http_block_reading
。 - 这意味着:
- 当Nginx检测到客户端发送新数据时,会调用
ngx_http_block_reading
,而非直接处理数据。
- 当Nginx检测到客户端发送新数据时,会调用
ngx_http_handler(r);
ngx_http_handler(r)
是 Nginx HTTP 请求处理的核心入口函数,负责:
- 启动 HTTP 请求的正式处理流程,包括各个阶段(如
rewrite
、access
、content
)的执行。 - 协调 HTTP 模块(如
ngx_http_core_module
、ngx_http_proxy_module
)按阶段处理请求。 - 最终生成响应并发送给客户端(或终止请求)。