Skip to content

answer Expect: 100-continue once per request in ParseHttpMessage - #3704

Merged
chenBright merged 1 commit into
apache:masterfrom
sahvx655-wq:http-expect-once
Nov 3, 2026
Merged

chenBright merged 1 commit into
apache:masterfrom
sahvx655-wq:http-expect-once

Conversation

@sahvx655-wq

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: resolve

Problem Summary:

ParseHttpMessage() answers Expect: 100-continue whenever it is called on a request whose headers are complete but whose body is not, and nothing records that the expectation was already answered. InputMessenger::OnNewMessages() calls the parser again after every read(), so a request whose body arrives in several reads is answered with one HTTP/1.1 100 Continue per read instead of once per request. With the new test on master, a body sent in four pieces drew four extra interim responses in front of the 200 OK. RFC 9110 section 10.1.1 has the server send the 100 (Continue) right after the header section and lets it omit the response once some of the content has arrived; it never calls for one per read.

The interim response is written with ignore_eovercrowded, so it is not subject to socket_max_unwritten_bytes. A client that sends the headers, then trickles the body one byte per segment and never reads, makes the server queue one interim response per segment with no cap. This happens in the parser, before any service or ServerOptions.auth is involved. Well-behaved clients see it too: a large upload with Expect: 100-continue gets a stream of interim responses, one per server read.

What is changed and the side effects?

Changed:

  • HttpContext records that ParseHttpMessage() has dealt with the Expect header of the request, so the interim response is written once. The header itself stays on the request, so services still see it (the existing HttpTest.http_expect relies on that).
  • Added HttpTest.http_expect_answered_once in test/brpc_http_rpc_protocol_unittest.cpp: headers first, then the body in pieces with a pause between them. It fails on master (a second 100 Continue arrives before the 200 OK) and passes with the change.

Side effects:

  • Performance effects: none on the normal path; one header lookup less per read of a partially received body.

  • Breaking backward compatibility: no. A request still gets exactly one 100 Continue; only the repeats go away.


Check List:

Tests run (CMake Debug build on Linux): brpc_http_rpc_protocol_unittest (66 tests), brpc_http_message_unittest, brpc_server_unittest and brpc_builtin_service_unittest, all passing.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The duplicate-response fix is covered by per-request Expect handling state and a fragmented-body regression test, with no active review issues remaining.

No open issues 🎉

What changed in this PR

This pull request fixes duplicate HTTP/1.1 100 Continue responses when a request body arrives across multiple reads. It tracks per-request Expect handling and adds regression coverage for fragmented request bodies.

Changes:

  • Track whether the Expect header has already been processed.
  • Emit 100 Continue only once per request.
  • Add a test verifying a single interim response followed by 200 OK.
File Description
test/​brpc_http_rpc_protocol_unittest.cpp Adds fragmented-body regression coverage for duplicate interim responses.
src/​brpc/​policy/​http_rpc_protocol.h Adds per-request state tracking for handled Expect headers.
src/​brpc/​policy/​http_rpc_protocol.cpp Prevents repeated 100 Continue responses during incremental parsing.

Review effort: Lite

@chenBright chenBright left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@chenBright
chenBright merged commit 7c7ad12 into apache:master Nov 3, 2026
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants