nginx worker 进程不直接解析 http 协议语法,而是通过 epoll 边收边判请求头,结构化为 ngx_table_elt_t 链表,经 header filter 阶段过滤重写后,再序列化输出,全程内存操作、事件驱动。

Nginx 的 Worker Process 并不直接“解析 HTTP 协议”本身(比如语法校验、语义分析),而是按 HTTP 协议规范,分阶段、结构化地处理请求行、请求头、响应行、响应头等关键字段,整个过程基于内存操作、事件驱动和模块化设计,核心目标是高效提取、转换、过滤并为后续处理提供结构化数据。
Worker 进程如何读取并识别 HTTP 请求头
Worker 进程通过 epoll(Linux)等 I/O 多路复用机制监听 socket 读事件。当客户端数据到达时,调用 ngx_http_wait_request_handler 开始接收:
- 使用固定大小缓冲区(默认 1024 字节)分块读取原始字节流
- 每次读取后立即尝试解析:先找
\r\n\r\n空行位置,界定 header 与 body 边界 - 从起始位置逐行提取:第一行为请求行(如
GET /path HTTP/1.1),后续为 header 字段(如Host: example.com) - 遇到非法格式(如缺少空行、换行符混乱)会返回 400 错误,不继续解析
该阶段不等待完整请求到来,而是边收边判,保证低延迟和高吞吐。
请求头被结构化为内部数据结构
解析后的 header 不以原始字符串保存,而是转为 ngx_table_elt_t 类型的链表节点,挂载在 r->headers_in 中:
- 每个字段含
key(小写归一化)、value、hash(用于 O(1) 查找)、skip(是否忽略输出) - 常见 header 有快捷访问字段,例如:
-
r->headers_in.host→ 解析后的 Host 值 -
r->headers_in.content_length_n→ Content-Length 转为整数(若合法) -
r->headers_in.user_agent→ 客户端 UA 字符串
-
- 多值 header(如多个
Cookie或Set-Cookie)保留为链表,支持遍历获取全部
这种结构让后续模块能快速访问、修改,避免重复字符串匹配。
Header Filter 阶段完成过滤与重写
所有已注册的 HTTP header filter 模块(如 ngx_http_proxy_header_filter、ngx_http_headers_filter)按顺序执行:
- 根据配置决定是否跳过某些 header:
-
proxy_hide_header X-Powered-By;→ 对应字段skip = 1 -
proxy_pass_request_headers off;→ 所有请求头默认不透传
-
- 支持动态添加或覆盖 header:
-
add_header X-Frame-Options DENY;→ 插入新字段 -
proxy_set_header Host $host;→ 替换 Host 值
-
- 修改仅作用于内存结构,不影响原始字节流
这个阶段发生在 header 解析完成后、准备发送响应前,是反向代理中 header 控制的核心环节。
响应头解析同样遵循四步流程
Worker 在反向代理场景下接收上游响应时,对响应头执行对称处理:
-
header parsing:识别状态行(
HTTP/1.1 200 OK)和后续 header,以\r\n\r\n结束 -
internal representation:存入
r->upstream->headers_in链表,提供content_length_n、last_modified_time等字段 -
filtering:应用
proxy_hide_header、proxy_ignore_headers等指令控制输出 - output preparation:将结构化 header 序列化为标准 HTTP 头块,拼入响应报文发送给客户端
整个过程无磁盘 I/O,纯内存操作,由事件循环驱动,与请求处理完全异步解耦。
不复杂但容易忽略











