1 定义ngx_http_handler 函数 定义在 ./nginx-1.24.0/src/http/ngx_http_core_module.cvoidngx_http_handler(ngx_http_request_t*r){ngx_http_core_main_conf_t*cmcf;r-connection-log-actionNULL;if(!r-internal){switch(r-headers_in.connection_type){case0:r-keepalive(r-http_versionNGX_HTTP_VERSION_10);break;caseNGX_HTTP_CONNECTION_CLOSE:r-keepalive0;break;caseNGX_HTTP_CONNECTION_KEEP_ALIVE:r-keepalive1;break;}r-lingering_close(r-headers_in.content_length_n0||r-headers_in.chunked);r-phase_handler0;}else{cmcfngx_http_get_module_main_conf(r,ngx_http_core_module);r-phase_handlercmcf-phase_engine.server_rewrite_index;}r-valid_location1;#if(NGX_HTTP_GZIP)r-gzip_tested0;r-gzip_ok0;r-gzip_vary0;#endifr-write_event_handlerngx_http_core_run_phases;ngx_http_core_run_phases(r);}ngx_http_handler 函数 是 Nginx 处理 HTTP 请求的总入口函数。 它根据请求类型外部客户端请求或内部重定向初始化 Keep-Alive、延迟关闭等标志 确定阶段处理的起始点然后将写事件处理器设置为 ngx_http_core_run_phases 并立即调用 从而启动 Nginx 著名的 11 阶段异步处理链驱动整个请求生命周期的运转。2 详解1 函数签名voidngx_http_handler(ngx_http_request_t*r)返回值 void无返回值。参数 ngx_http_request_t *r 指向 当前请求的上下文结构体 此时请求行和请求头已解析完毕 等待进入业务处理阶段。2 逻辑流程1 局部变量 2 清空日志动作 3 请求来源分流与初始化 4 重置 location 有效标志 5 设置写事件处理器并立即执行1 局部变量{ngx_http_core_main_conf_t*cmcf;声明一个指向 HTTP 核心模块主配置的指针 cmcf2 清空日志动作r-connection-log-actionNULL;将连接关联日志对象中的 action 字段置为 NULL action 是一个字符串描述当前正在进行的操作会在错误日志中输出。 请求进入新阶段时旧的描述不再适用需清空待后续阶段按需重新设置3 请求来源分流与初始化if(!r-internal){switch(r-headers_in.connection_type){case0:r-keepalive(r-http_versionNGX_HTTP_VERSION_10);break;caseNGX_HTTP_CONNECTION_CLOSE:r-keepalive0;break;caseNGX_HTTP_CONNECTION_KEEP_ALIVE:r-keepalive1;break;}r-lingering_close(r-headers_in.content_length_n0||r-headers_in.chunked);r-phase_handler0;}else{cmcfngx_http_get_module_main_conf(r,ngx_http_core_module);r-phase_handlercmcf-phase_engine.server_rewrite_index;}r-internal标志位。 如果请求由内部跳转产生则值为非零 否则为 0表示来自客户端的初始外部请求。#1 外部请求根据 connection_type 分别处理case 0请求未包含 Connection 头部需根据 HTTP 版本使用默认行为 如果 HTTP 版本大于 1.0即 HTTP/1.1 及以上默认开启 Keep-Alive 否则默认关闭NGX_HTTP_CONNECTION_CLOSE请求头明确包含 Connection: close。 强制关闭持久连接即使 HTTP 版本为 1.1也必须在响应后关闭连接。 尊重客户端的意愿允许其主动要求关闭连接例如为了释放资源。NGX_HTTP_CONNECTION_KEEP_ALIVE 请求头包含 Connection: keep-alive常见于 HTTP/1.0 客户端。 强制开启 Keep-Alive即使 HTTP/1.0 默认不保持连接。设置延迟关闭标志 lingering_close标记是否需要在关闭连接前执行“延迟关闭” content_length_n 0 请求带有非零的 Content-Length即存在请求体。 chunked 请求使用了分块传输编码 满足任一条件即表示客户端可能仍在发送数据。 直接关闭连接会导致客户端收到 RST可能使其无法接收到最后的响应。 启用延迟关闭后Nginx 会在发送完响应后继续读取并丢弃剩余请求体数据 实现优雅的 TCP 连接关闭确保可靠传输。设置阶段处理器起始索引 phase_handler 整数索引指示下一次应执行哪个阶段处理器。 赋值 0从第一个阶段NGX_HTTP_POST_READ_PHASE开始执行。 外部请求必须完整经历所有 11 个阶段如访问控制、内容生成等 从头开始保证了处理链的完整性。#2 内部请求 执行条件r-internal 非零内部重定向或子请求。cmcf 获取 HTTP 核心模块的主配置其中 phase_engine 包含了所有阶段处理器的布局。 server_rewrite_index NGX_HTTP_SERVER_REWRITE_PHASE 阶段第一个处理器的索引。 将 phase_handler 直接设置为该索引 从而跳过 POST_READ、PREACCESS、ACCESS 等已执行过的阶段 从 server_rewrite 阶段重新开始。 内部请求本身已具备足够的上下文无需重复全局安全检查 直接从 URL 重写阶段切入可以重新匹配 location、执行 rewrite 规则 既避免冗余处理又保证内部跳转逻辑的正确实施。4 重置 location 有效标志r-valid_location1;#if(NGX_HTTP_GZIP)r-gzip_tested0;r-gzip_ok0;r-gzip_vary0;#endif重置 location 匹配标志 valid_location 标志位表示当前请求的 location 配置是否仍然有效。 赋值 1允许或要求后续的 find config 阶段重新进行 location 匹配。 逻辑无论是外部请求第一次匹配 location还是内部重定向后需要重新确定 location这里都重置为 1 通知阶段引擎需要重新执行 ngx_http_core_find_config_phase并在匹配成功后将其置为 0。 意义确保每个请求都有正确的 location 配置上下文为后续的访问控制、内容处理等提供依据。重置 Gzip 相关标志5 设置写事件处理器并立即执行r-write_event_handlerngx_http_core_run_phases;ngx_http_core_run_phases(r);}挂载写事件处理函数 当请求可继续执行时如写事件就绪、延迟队列取出会被调用立即启动阶段处理链 立刻执行 ngx_http_core_run_phases 该函数会依据 r-phase_handler 依次调用各阶段处理器。
ngx_http_handler
1 定义ngx_http_handler 函数 定义在 ./nginx-1.24.0/src/http/ngx_http_core_module.cvoidngx_http_handler(ngx_http_request_t*r){ngx_http_core_main_conf_t*cmcf;r-connection-log-actionNULL;if(!r-internal){switch(r-headers_in.connection_type){case0:r-keepalive(r-http_versionNGX_HTTP_VERSION_10);break;caseNGX_HTTP_CONNECTION_CLOSE:r-keepalive0;break;caseNGX_HTTP_CONNECTION_KEEP_ALIVE:r-keepalive1;break;}r-lingering_close(r-headers_in.content_length_n0||r-headers_in.chunked);r-phase_handler0;}else{cmcfngx_http_get_module_main_conf(r,ngx_http_core_module);r-phase_handlercmcf-phase_engine.server_rewrite_index;}r-valid_location1;#if(NGX_HTTP_GZIP)r-gzip_tested0;r-gzip_ok0;r-gzip_vary0;#endifr-write_event_handlerngx_http_core_run_phases;ngx_http_core_run_phases(r);}ngx_http_handler 函数 是 Nginx 处理 HTTP 请求的总入口函数。 它根据请求类型外部客户端请求或内部重定向初始化 Keep-Alive、延迟关闭等标志 确定阶段处理的起始点然后将写事件处理器设置为 ngx_http_core_run_phases 并立即调用 从而启动 Nginx 著名的 11 阶段异步处理链驱动整个请求生命周期的运转。2 详解1 函数签名voidngx_http_handler(ngx_http_request_t*r)返回值 void无返回值。参数 ngx_http_request_t *r 指向 当前请求的上下文结构体 此时请求行和请求头已解析完毕 等待进入业务处理阶段。2 逻辑流程1 局部变量 2 清空日志动作 3 请求来源分流与初始化 4 重置 location 有效标志 5 设置写事件处理器并立即执行1 局部变量{ngx_http_core_main_conf_t*cmcf;声明一个指向 HTTP 核心模块主配置的指针 cmcf2 清空日志动作r-connection-log-actionNULL;将连接关联日志对象中的 action 字段置为 NULL action 是一个字符串描述当前正在进行的操作会在错误日志中输出。 请求进入新阶段时旧的描述不再适用需清空待后续阶段按需重新设置3 请求来源分流与初始化if(!r-internal){switch(r-headers_in.connection_type){case0:r-keepalive(r-http_versionNGX_HTTP_VERSION_10);break;caseNGX_HTTP_CONNECTION_CLOSE:r-keepalive0;break;caseNGX_HTTP_CONNECTION_KEEP_ALIVE:r-keepalive1;break;}r-lingering_close(r-headers_in.content_length_n0||r-headers_in.chunked);r-phase_handler0;}else{cmcfngx_http_get_module_main_conf(r,ngx_http_core_module);r-phase_handlercmcf-phase_engine.server_rewrite_index;}r-internal标志位。 如果请求由内部跳转产生则值为非零 否则为 0表示来自客户端的初始外部请求。#1 外部请求根据 connection_type 分别处理case 0请求未包含 Connection 头部需根据 HTTP 版本使用默认行为 如果 HTTP 版本大于 1.0即 HTTP/1.1 及以上默认开启 Keep-Alive 否则默认关闭NGX_HTTP_CONNECTION_CLOSE请求头明确包含 Connection: close。 强制关闭持久连接即使 HTTP 版本为 1.1也必须在响应后关闭连接。 尊重客户端的意愿允许其主动要求关闭连接例如为了释放资源。NGX_HTTP_CONNECTION_KEEP_ALIVE 请求头包含 Connection: keep-alive常见于 HTTP/1.0 客户端。 强制开启 Keep-Alive即使 HTTP/1.0 默认不保持连接。设置延迟关闭标志 lingering_close标记是否需要在关闭连接前执行“延迟关闭” content_length_n 0 请求带有非零的 Content-Length即存在请求体。 chunked 请求使用了分块传输编码 满足任一条件即表示客户端可能仍在发送数据。 直接关闭连接会导致客户端收到 RST可能使其无法接收到最后的响应。 启用延迟关闭后Nginx 会在发送完响应后继续读取并丢弃剩余请求体数据 实现优雅的 TCP 连接关闭确保可靠传输。设置阶段处理器起始索引 phase_handler 整数索引指示下一次应执行哪个阶段处理器。 赋值 0从第一个阶段NGX_HTTP_POST_READ_PHASE开始执行。 外部请求必须完整经历所有 11 个阶段如访问控制、内容生成等 从头开始保证了处理链的完整性。#2 内部请求 执行条件r-internal 非零内部重定向或子请求。cmcf 获取 HTTP 核心模块的主配置其中 phase_engine 包含了所有阶段处理器的布局。 server_rewrite_index NGX_HTTP_SERVER_REWRITE_PHASE 阶段第一个处理器的索引。 将 phase_handler 直接设置为该索引 从而跳过 POST_READ、PREACCESS、ACCESS 等已执行过的阶段 从 server_rewrite 阶段重新开始。 内部请求本身已具备足够的上下文无需重复全局安全检查 直接从 URL 重写阶段切入可以重新匹配 location、执行 rewrite 规则 既避免冗余处理又保证内部跳转逻辑的正确实施。4 重置 location 有效标志r-valid_location1;#if(NGX_HTTP_GZIP)r-gzip_tested0;r-gzip_ok0;r-gzip_vary0;#endif重置 location 匹配标志 valid_location 标志位表示当前请求的 location 配置是否仍然有效。 赋值 1允许或要求后续的 find config 阶段重新进行 location 匹配。 逻辑无论是外部请求第一次匹配 location还是内部重定向后需要重新确定 location这里都重置为 1 通知阶段引擎需要重新执行 ngx_http_core_find_config_phase并在匹配成功后将其置为 0。 意义确保每个请求都有正确的 location 配置上下文为后续的访问控制、内容处理等提供依据。重置 Gzip 相关标志5 设置写事件处理器并立即执行r-write_event_handlerngx_http_core_run_phases;ngx_http_core_run_phases(r);}挂载写事件处理函数 当请求可继续执行时如写事件就绪、延迟队列取出会被调用立即启动阶段处理链 立刻执行 ngx_http_core_run_phases 该函数会依据 r-phase_handler 依次调用各阶段处理器。