nginx worker进程在接收客户端连接后,先完整读取并结构化解析请求头:通过事件驱动与状态机在用户态内存中逐字节解析请求行及头部字段,存入r->headers_in链表并提供快捷访问,再经header filter模块过滤修改,最终决定响应中包含的头部字段。

Nginx 的 Worker 进程在收到客户端连接后,并不直接转发请求,而是先完整读取并结构化解析请求头(Request Headers),这是整个 HTTP 处理流程的起点和关键环节。解析发生在用户态内存中,全程无磁盘 I/O,依赖事件驱动与状态机协作完成。
从连接建立到请求头读取
当操作系统完成 TCP 三次握手后,内核按负载均衡策略将新连接分发给某个 Worker 进程。该进程调用 accept() 获取 socket 句柄,分配连接内存池(默认 512 字节),并注册读事件到 epoll。一旦客户端发送数据,epoll 触发回调 ngx_http_wait_request_handler,Worker 开始从内核缓冲区读取字节流。
- 初始读取使用
client_header_buffer_size(默认 1k)内存;若请求头超长,自动启用large_client_header_buffers(如 4×8k)继续读取 - 超时由
client_header_timeout控制(默认 60s),超时未收完则断连 - 读取内容暂存于连接上下文的 buffer 中,等待解析
请求行与头部字段的状态机解析
Worker 调用 HTTP 模块内置的状态机(如 ngx_http_parse_request_line 和 ngx_http_parse_header_line)逐字节处理原始字节流:
- 先识别请求行(如
GET /api/v1/user HTTP/1.1),提取 method、uri、http version 并存入r->method、r->uri等字段 - 随后循环解析每行 header:跳过空格与换行,分离 key/value,对 key 忽略大小写归一化(
content-type和Content-Type视为同一字段) - 遇到空行(
\r\n\r\n)即判定请求头结束,后续字节归入 request body 缓冲区
结构化存储与快速访问
解析后的 header 不保留原始字符串,而是构造成 ngx_table_elt_t 链表节点,挂载到 r->headers_in 中:
- 每个节点含
key、value、hash(用于 O(1) 查找)、skip(是否忽略输出)等字段 - 常见 header 有快捷指针:如
r->headers_in.host、r->headers_in.content_length_n(已转为整数)、r->headers_in.cookies(链表) - 未预定义字段仍保留在通用链表中,可通过
ngx_list_part()遍历访问
过滤与模块介入时机
解析完成后,Worker 按注册顺序调用所有启用的 header filter 模块(如 ngx_http_realip_filter、ngx_http_headers_filter):
- 模块可修改或删除 header 字段(例如通过
underscores_in_headers on允许下划线,或ignore_invalid_headers off保留非法字段) -
proxy_set_header、add_header等指令在此阶段生效,影响最终发往上层或客户端的 header 集合 - 最终决定哪些 header 进入响应构造阶段,哪些被跳过(
skip = 1)











