handler模块不直接处理http分块传输,而是由output filter链中的ngx_http_chunked_filter_module自动封装;其职责是生成响应体、设置响应头(不设content-length),并通过ngx_http_output_filter交由filter链处理。

Handler 模块本身不直接处理 HTTP 分块传输(Chunked Transfer Encoding)——它不是网络协议解析器,而是 Nginx 中负责生成响应内容的逻辑单元。真正与分块传输相关的是:Handler 生成数据后,由 Nginx 的 output filter 链(特别是 ngx_http_chunked_filter_module)自动封装成 chunked 格式,再经底层发送。
Handler 模块的角色定位
Handler 是 Nginx 请求处理的核心阶段,职责是:
- 读取请求参数、校验权限、调用业务逻辑
- 准备响应体(如拼接 HTML、序列化 JSON、读取文件流)
- 设置响应头(如
Content-Type),但不设Content-Length - 调用
ngx_http_output_filter()将数据交给 filter 链处理
分块传输如何被自动启用
当 Handler 不设置 Content-Length 头,且未禁用分块编码时,Nginx 会在 response header 中自动添加:
随后,所有通过 ngx_http_output_filter() 写入的数据,都会被 chunked_filter 模块逐段包装为标准 chunk 格式:
-
5\r\nHello\r\n(5 字节数据块) -
6\r\nWorld!\r\n(6 字节数据块) -
0\r\n\r\n(结束块)
实战中 Handler 的关键操作
要让分块传输生效,Handler 必须做到以下几点:
- 避免调用
r->headers_out.content_length_n或设置Content-Length响应头 - 对大响应或流式场景,使用多次
ngx_http_output_filter()调用(而非一次性写完) - 若需手动控制分块边界(如日志流、SSE),可在每次写入前插入自定义逻辑,但无需手拼
"%x\r\n"—— chunked_filter 已接管格式化 - 确保返回值检查:每次
ngx_http_output_filter()成功后才继续下一块,防止阻塞或丢数据
常见误区澄清
❌ 不要在 Handler 里自己拼 "5\r\nHello\r\n" —— 这会破坏 Nginx 的 filter 机制,导致双编码或协议错误
✅ 正确做法是:专注业务数据生成,把协议封装完全交给 output filter 链
⚠️ 注意:若 upstream 返回了 Transfer-Encoding: chunked,Nginx 默认会解码;如需透传,需配置 proxy_buffering off 并启用 chunked_transfer_encoding on










