Conversation
send_headers stored extract_method_header() on every header block, including trailers, which carry no :method, so the remembered b"HEAD" was replaced by None and _initialize_content_length stopped applying the HEAD exemption. A response to a HEAD request that was closed with trailers then raised InvalidBodyLengthError on a bodyless message that RFC 9113 8.1.1 permits. Store the method only when the block carries one.
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.
A request that was closed with a trailers block lost the
:methodit was sent with, so the HEAD exemption in_initialize_content_lengthstopped applying and a bodyless response was rejected.send_headersstoredextract_method_header(bytes_headers)on every header block it sent. A trailers block carries no:method, so the helper returnsNoneand the rememberedb"HEAD"was overwritten. The next200withcontent-length: 1234and an empty DATA frame carrying END_STREAM then raised:RFC 9113 § 8.1.1 lists 204, 304 and the response to HEAD as messages defined to have no content. Without the exemption the check has nothing to stand on, and one frame of framing noise on the request side decides whether a legitimate response is accepted.
Storing the method only when the block carries one keeps the exemption for the whole request. This is the
send_headershalf of the two smaller defects reported in #1330; theremotely_pushedhalf (a pushed stream never records its method at all) is a separate change and is not touched here.Verification
On
bc239afthe new test fails with the error above, on5ac90d3it passes.pytest tests/ -q→ 1664 passed.pytest tests/ -q --cov=h2→ 100.00%, the enforced threshold, withstream.pyat 100% statements and branches.ruff check src/andmypy --strict src/h2/stream.pyboth clean.