Skip to content

Treat an empty Transfer-Encoding list as no transfer codings - #526

Open
ericmj wants to merge 1 commit into
http1-te-parametersfrom
http1-empty-te
Open

ericmj wants to merge 1 commit into
http1-te-parametersfrom
http1-empty-te

Conversation

@ericmj

@ericmj ericmj commented Oct 16, 2026

Copy link
Copy Markdown
Member

A Transfer-Encoding field with no list elements, such as an empty value or ",", failed the response with :empty_token_list and closed the connection. For a response to HEAD this happened before the rule that such a response has no body, and a comma-only field between two nonempty Transfer-Encoding fields failed the response instead of being ignored.

RFC 9110 5.6.1 allows a #transfer-coding list with zero elements, so such a field now adds no transfer coding when the framing is chosen. A response with only an empty Transfer-Encoding and no Content-Length has no framing, so its body is read until the connection closes (RFC 9112 6.3). The field still counts as present: with Content-Length it's an error, and it makes an HTTP/1.0 response, including a 1xx one, close the connection (RFC 9112 6.1).

Transfer-Encoding values are parsed only where they decide the framing, combined into one value as on the request side, so a malformed value no longer fails a response to HEAD, a 204 or 304 response, or a 2xx response to CONNECT, whose Transfer-Encoding RFC 9110 9.3.6 says to ignore. Where it does fail, the error comes after the :headers event (with :stream_headers the field itself can be emitted first) and not while the header section is incomplete, other header errors in the same section are reported instead of it, and with Content-Length the error is :transfer_encoding_and_content_length instead of {:invalid_token_list, value}.

On the request side, a Transfer-Encoding field with no codings passed to request/5 with a streamed body counts as no codings: when chunked is appended to such a last field it replaces the empty value.

A Transfer-Encoding field with no list elements, such as an empty value
or ",", failed the response with :empty_token_list and closed the
connection. For a response to HEAD this happened before the rule that
such a response has no body, and a comma-only field between two
nonempty Transfer-Encoding fields failed the response instead of being
ignored.

RFC 9110 5.6.1 allows a #transfer-coding list with zero elements, so
such a field now adds no transfer coding when the framing is chosen. A
response with only an empty Transfer-Encoding and no Content-Length has
no framing, so its body is read until the connection closes (RFC 9112
6.3). The field still counts as present: with Content-Length it's an
error, and it makes an HTTP/1.0 response, including a 1xx one, close
the connection (RFC 9112 6.1).

Transfer-Encoding values are parsed only where they decide the framing,
combined into one value as on the request side, so a malformed value no
longer fails a response to HEAD, a 204 or 304 response, or a 2xx
response to CONNECT, whose Transfer-Encoding RFC 9110 9.3.6 says to
ignore. Where it does fail, the error comes after the :headers event
(with :stream_headers the field itself can be emitted first) and not
while the header section is incomplete, other header errors in the same
section are reported instead of it, and with Content-Length the error is
:transfer_encoding_and_content_length instead of {:invalid_token_list,
value}.

On the request side, a Transfer-Encoding field with no codings passed to
request/5 with a streamed body counts as no codings: when chunked is
appended to such a last field it replaces the empty value.
@ericmj
ericmj added this pull request to stack #530 October 16, 2026 13:03
@github-actions

Copy link
Copy Markdown

Coverage Report for CI Build 33

Warning

No base build found for commit 96bc2b5 on http1-te-parameters.
Coverage changes can't be calculated without a base build.
If a base build is processing, this comment will update automatically when it completes.

Coverage: 90.514%

Details

  • Patch coverage: 9 of 9 lines across 2 files are fully covered (100%).

Uncovered Changes

No uncovered changes found.

Coverage Regressions

Requires a base build to compare against. How to fix this →


Coverage Stats

Coverage Status
Relevant Lines: 2003
Covered Lines: 1813
Line Coverage: 90.51%
Coverage Strength: 712.93 hits per line

💛 - Coveralls

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.

1 participant