http: Transfer-Encoding chunked plus Content-Length hangs forever (CL branch shadows the chunked path)

未关闭 适合新手
#12,656 3 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

@sarankumar1325 已经在做这个了。

开始于 2026年10月29日。

  • #12692 来自 @sarankumar1325 —— 未关闭

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
76/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
c

调研方向

从 lib/monkey/mk_server/mk_http_parser.c 中的 REQ_LEVEL_BODY 分支开始,跟踪 mk_http_parser_is_content_chunked() 和 http_parser_transfer_encoding_chunked() 的调用路径。使用两个请求头重现提供的请求,并将其与不含 Content-Length 的 chunked 请求进行比较。请求被解析为 chunked 并返回 201,而不是挂起,即表示完成。

由索引模型根据 Issue 内容生成。

描述

Bug Report

Describe the bug

A request carrying both Transfer-Encoding: chunked and Content-Length never completes. The server reads the
whole chunked body, then waits forever for Content-Length bytes that will never arrive, and the request is never
processed or answered.

This is the classic request-smuggling header pair, so it matters beyond a simple hang.

To Reproduce

POST / HTTP/1.1
Host: x
Content-Type: application/json
Transfer-Encoding: chunked
Content-Length: 100

7\r\n{"a":1}\r\n0\r\n\r\n

Result: no response (hangs to the 10 s timeout), and no record is emitted. Reproducible every time. The same
request with Content-Length: 2 instead of 100 also hangs, so it is not about the value — merely having the
header is enough.

Without Content-Length the identical chunked request returns 201.

Root cause

lib/monkey/mk_server/mk_http_parser.c, in the main parse loop at REQ_LEVEL_BODY:

else if (p->level == REQ_LEVEL_BODY) {
    if (p->header_content_length > 0) {
        p->body_received = len - p->start;
        if ((len - p->start) < p->header_content_length) {
            return MK_HTTP_PARSER_PENDING;      /* <- never gets past here */
        }
        ...
    }
    return mk_http_parser_ok(req, p, buffer, buf_len, server);
}

The chunked handling lives in mk_http_parser_ok(), which is only reached after this branch. So when
Content-Length is present the CL path is taken first and returns PENDING, and mk_http_parser_ok() — which
would have dispatched to http_parser_transfer_encoding_chunked() — is never called.

The branch should be if (p->header_content_length > 0 && !mk_http_parser_is_content_chunked(p)), or the chunked
case should be checked first.

Expected behavior

Transfer-Encoding: chunked takes precedence over Content-Length (RFC 9112 §6.3), so the request should be
parsed as chunked and answered with 201.

Your Environment

  • Fluent Bit 5.1.5 (fluent/fluent-bit:latest)
  • Linux, aarch64, official container image
  • Input: http plugin, default settings

Impact

Pre-auth. Any client or proxy that sends both headers — common, since many stacks add Content-Length alongside
chunked encoding — gets a hang and a lost record. Because the two headers are interpreted differently from what
RFC 9112 requires, it is also a request-smuggling candidate when Fluent Bit sits behind a proxy that prefers
Content-Length.

主要语言
C
星标
8.2k
派生
2k
平均合并
3 天 20 小时
30 天内合并 PR
99

环境准备

在 Codespaces 中打开

在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

fluent/fluent-bit 的其他 Issue

查看 fluent/fluent-bit 的全部 Issue

相似的 Issue

更多 C Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。