gh-150499: http.server: drain unread request body on persistent connections (RFC 7230 §6.3)#150508
Open
tonghuaroot wants to merge 1 commit into
Open
gh-150499: http.server: drain unread request body on persistent connections (RFC 7230 §6.3)#150508tonghuaroot wants to merge 1 commit into
tonghuaroot wants to merge 1 commit into
Conversation
… connections Follow-up to pythongh-150499 (paired with python#150500 which lands the §3.3.3 rules). Wrap rfile with a small byte-counting reader for the duration of the request and, after the handler returns, drain any unread declared body up to a 1 MiB cap (or close the connection if the remainder is larger). Without this, the next iteration of the keep-alive loop parses the leftover body as a request line, per RFC 7230 section 6.3. The wrapper proxies read, read1, readline, readinto, and readinto1 and falls back to __getattr__ for everything else, so existing handlers (including the ServerHandler chain in wsgiref.simple_server, which passes self.rfile directly to WSGI applications) continue to work unchanged. Add RFC7230BodyDrainTestCase asserting that the leftover body is not parsed as the next request line on a persistent connection. Signed-off-by: tonghuaroot <tonghuaroot@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes gh-150499 (paired with #150500 which lands the §3.3.3 rules).
Summary
After #150500 lands the §3.3.3 rule-3 / rule-4 rejections, requests
that make it past
parse_requestmay still carry an unread declaredbody that the handler does not consume. Per RFC 7230 §6.3 the server
must either drain it or close the connection. Without that, the next
iteration of the keep-alive loop parses the leftover bytes as a
request line.
handle_one_requestnow wrapsself.rfilewith a small byte-countingreader for the duration of the request. After the handler returns,
any unread declared body is drained up to a 1 MiB cap; over the cap
the connection is closed instead.
The wrapper proxies
read,read1,readline,readinto, andreadinto1and falls back to__getattr__for everything else, soexisting handlers (including the
ServerHandlerchain inwsgiref.simple_server, which passesself.rfiledirectly to WSGIapplications) continue to work unchanged.
Tests
Lib/test/test_httpservers.pyaddsRFC7230BodyDrainTestCasewithtest_body_drained_on_persistent_connection, asserting the leftoverbody is not parsed as the next request line on a persistent
connection. Full
test_httpservers(103 tests) andtest_wsgiref(38 tests) suites also pass with no regression.
News entry
Misc/NEWS.d/next/Library/2026-05-27-09-15-22.gh-issue-150499.dBoDr4.rst.Backport
This PR targets
mainonly.