http_server: accept empty HTTP header values - #12223
Conversation
The Monkey parser fix was merged upstream in monkey/monkey#444 and is bundled in Fluent Bit by fluent#12212 as part of Monkey 1.8.9. Propagate MK_HTTP_PARSER_ERROR to the HTTP server provider so malformed requests are closed instead of resetting the parser and remaining pending. Keep this Fluent Bit-specific error handling separate from the bundled Monkey sources. Signed-off-by: kimonus <kimonus@users.noreply.github.com>
Send real HTTP/1 requests containing empty and whitespace-only generic headers and require the accepted request to reach the input callback. Also verify that an invalid empty Upgrade field is not ingested. Use portable socket types, handle partial writes and reads, and reject timeouts or incomplete HTTP status lines so the regression runs on the supported runtime-test platforms. The test exercises Monkey 1.8.9 now bundled in Fluent Bit by fluent#12212. Signed-off-by: kimonus <kimonus@users.noreply.github.com>
Add real-server POST coverage matching fluent#12174 for empty and whitespace-only generic fields, and verify that the request body is forwarded successfully. Cover empty Connection and Transfer-Encoding values plus empty and whitespace-only Content-Length fields followed immediately by numeric header or body data. Rejected requests must close or return 400, never hang or forward a payload. These tests exercise Monkey 1.8.9 now bundled in Fluent Bit by fluent#12212. Signed-off-by: kimonus <kimonus@users.noreply.github.com>
📝 WalkthroughWalkthroughThe HTTP server now preserves split HTTP/2 prefaces and reports HTTP/1 parser errors. Runtime and integration tests cover empty headers, invalid ChangesHTTP protocol regressions
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related issues
Possibly related PRs
Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant Client
participant HTTPServer
participant HTTP2Session
Client->>HTTPServer: Send split HTTP/2 preface
HTTPServer->>HTTPServer: Wait for remaining preface bytes
HTTPServer->>HTTP2Session: Ingest accumulated preface
HTTP2Session-->>Client: Return settings response
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/runtime/in_http.c`:
- Around line 638-641: Extend the rejection assertion in tests/runtime/in_http.c
around get_output_num() to wait for the same full dispatch and flush observation
interval used by the accepted raw-request path before comparing output counts.
In tests/integration/scenarios/in_http/tests/test_in_http_001.py lines 246-255,
add a bounded no-output observation covering at least one configured output
flush interval before asserting data_storage["payloads"] is empty.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 045d6dc3-3460-4597-b750-46f65f7466f6
📒 Files selected for processing (3)
src/http_server/flb_http_server_http1.ctests/integration/scenarios/in_http/tests/test_in_http_001.pytests/runtime/in_http.c
Wait for the same dispatch and flush observation window used by accepted raw requests before confirming that malformed requests do not reach the output callback. Signed-off-by: kimonus <kimonus@users.noreply.github.com>
Observe rejected requests for longer than one configured output flush interval, then check again after shutdown so delayed forwarding cannot make the regression pass incorrectly. Signed-off-by: kimonus <kimonus@users.noreply.github.com>
Keep protocol autodetection pending while a split HTTP/2 preface is incomplete. Feed all buffered bytes to nghttp2 after detection completes. Signed-off-by: kimonus <kimonus@users.noreply.github.com>
Send the client connection preface across separate reads. Verify that the server initializes HTTP/2 and returns its SETTINGS frame. Signed-off-by: kimonus <kimonus@users.noreply.github.com>
|
Thanks for the CI signal. I reproduced the failing max-connections case and found an interaction in protocol autodetection: the undecided version is I updated the branch so that:
New commits:
Verification against the rebuilt binary:
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/http_server/flb_http_server.c`:
- Around line 1402-1406: In the HTTP protocol autodetection flow, update the
HTTP/1 path after parser initialization to restore buffer and length from
session->incoming_data, matching the existing HTTP/2 handling, so all
accumulated bytes are replayed to the parser. Add a regression test that splits
an HTTP/1 request before the fourth byte and verify the request is parsed
successfully, including the relevant boundary size.
In `@tests/integration/scenarios/in_http/tests/test_in_http_001.py`:
- Around line 97-101: The test around the split preface writes must verify that
the server has observed and processed preface[:-2] before sending the remainder.
Replace the timing-only sleep in the test_in_http_001 scenario with a
server-visible synchronization mechanism or an explicit check that the
connection remains open after the first sendall, then send preface[-2:] plus
settings_frame.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: f2701275-8c46-4711-ad8c-81cd4d726f88
📒 Files selected for processing (2)
src/http_server/flb_http_server.ctests/integration/scenarios/in_http/tests/test_in_http_001.py
Make split request boundaries observable before sending the remainder. Cover HTTP/1 detection when the first read is shorter than four bytes. Signed-off-by: kimonus <kimonus@users.noreply.github.com>
|
@edsiper @cosmo0920 CodeRabbit has completed its latest review with no actionable comments, and all review threads are resolved. I updated the PR description with the final scope and verification evidence. The rebuilt binary passed the focused CTest targets 3/3; the complete affected integration scope passed 37/37 normally and 37/37 under strict Valgrind; and the exact six-scenario CI selection passed 27/27 in both modes. The full configured CTest run passed 204/205, with only the unrelated legacy flb-rt-out_td hard-coded /tmp/td.conf issue noted in the description. The fork workflows currently show action_required pending maintainer approval. Documentation is N/A because this changes no public configuration or documented interface, so the default docs-required label can be removed if you agree. When convenient, could you please approve the workflows and review this PR for the v5.1 milestone? Thank you. |
|
Thanks for merging this, Eduardo. I noticed that the post-merge HTTP lifecycle workflow passed 26/27 tests but failed the partial HTTP/2 preface max-connections case under strict Valgrind. The same selection passed on the PR and in our repeated local strict-Valgrind runs, so it appears timing-sensitive. I’m happy to investigate and prepare a small follow-up if you think it would be useful. |
Supersedes #12175, which GitHub auto-closed when the temporary base branch
for #12212 was removed after merge.
Fixes #12174.
Summary
The parser fix was merged upstream in monkey/monkey#444 and bundled in
Fluent Bit with Monkey 1.8.9 by #12212. This PR contains only the remaining
Fluent Bit-owned changes:
of being reset and left pending;
pass all accumulated preface bytes to nghttp2;
semantic headers;
in_httpcoverage for the original POST/body report,bounded
Content-Lengthparsing, and split HTTP/1 and HTTP/2 requests.No files under
lib/monkeyare changed.Behavior
Before this change, an invalid HTTP/1 request could leave a keep-alive client
without a response, and a split HTTP/2 preface could be routed to the HTTP/1
parser. After this change, invalid requests are rejected and incomplete HTTP/2
autodetection waits for the rest of the preface. Empty generic headers remain
accepted.
Testing
Ubuntu 24.04 Docker, GCC 13.3:
Result: full configure and build passed.
Result: focused CTest passed 3/3.
Result: 204/205 tests passed. The sole failure was the unrelated legacy
flb-rt-out_td, which depends on a hard-coded/tmp/td.confand leaves itspre-created
td.0output unconfigured when the repository sample config ismounted.
Targeted split-boundary regressions:
Result: 2/2 passed normally and 2/2 passed with
VALGRIND=1 VALGRIND_STRICT=1.Complete affected integration scope:
Result: 37/37 passed normally and 37/37 passed with
VALGRIND=1 VALGRIND_STRICT=1.The exact six-scenario
Input HTTP pause and lifecycle testsselection alsopassed in both modes: 27 passed and 167 deselected normally, then 27 passed and
167 deselected with strict Valgrind.
The CI-style full-PR commit-prefix checker and
git diff --checkpass againstthe current
masterbranch.PR template evidence
in_httpintegration configurations without changing user configuration.
newly built Fluent Bit v5.1.0 binary and exercise actual HTTP listeners.
both passed with strict Valgrind handling.
Representative clean Valgrind output:
Compatibility
No configuration, packaging, documentation, or bundled-library changes are
included. The runtime socket regression uses Fluent Bit's portable socket
types. Upstream Windows and macOS workflows are pending maintainer approval
for this fork PR.
Documentation
N/A. This fixes protocol parsing and error handling without changing public
configuration or documented user-facing interfaces. The default
docs-requiredlabel can be removed if the maintainers agree.Summary by CodeRabbit
Bug Fixes
Content-Lengthheaders without forwarding payloads.Upgradeheaders without producing unintended output.Connection, andTransfer-Encodingheaders.Tests