ngx_http_process_request

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 请求的核心函数,主要完成以下工作:

  1. SSL/TLS 验证(如果启用):

    • 检查是否为 HTTPS 请求,若客户端发送明文 HTTP 到 HTTPS 端口则拒绝。
    • 验证客户端证书(如果配置需要),包括证书有效性、是否提供证书(若必需)以及 OCSP 状态。
    • 失败时返回相应的错误(如 NGX_HTTP_TO_HTTPSNGX_HTTPS_CERT_ERROR)。
  2. 调整连接状态

    • 取消连接的读定时器(如果设置)。
    • 更新统计信息(如读写状态计数,仅在启用统计模块时)。
  3. 设置事件处理器

    • 将连接的读写事件处理器设置为 ngx_http_request_handler
    • 设置请求的读事件处理器为 ngx_http_block_reading(阻止进一步读取)。
  4. 转入请求处理

    • 调用 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,而非直接处理数据。

ngx_http_handler(r);

ngx_http_handler(r) 是 Nginx HTTP 请求处理的核心入口函数,负责:

  1. 启动 HTTP 请求的正式处理流程,包括各个阶段(如 rewriteaccesscontent)的执行。
  2. 协调 HTTP 模块(如 ngx_http_core_modulengx_http_proxy_module)按阶段处理请求。
  3. 最终生成响应并发送给客户端(或终止请求)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值