Skip to content

fix(http1): discard content-length in client responses that also have transfer-encoding - #4181

Open
dylanpulver wants to merge 1 commit into
hyperium:masterfrom
dylanpulver:client-te-cancels-content-length
Open

fix(http1): discard content-length in client responses that also have transfer-encoding#4181
dylanpulver wants to merge 1 commit into
hyperium:masterfrom
dylanpulver:client-te-cancels-content-length

Conversation

@dylanpulver

Copy link
Copy Markdown

#4124 fixed this for Server::parse. Client::parse has the same shape and was not touched, so a response carrying both transfer-encoding and content-length is framed correctly but keeps the canceled content-length, and the connection is still reused. Both header orders, unlike the server.

Against a raw server replying content-length: 10 + transfer-encoding: chunked with a 5-byte chunked body, on master:

response content-length header = Some("10")
body = b"hello" (5 bytes)
sender.ready() after the response = true
tcp connections accepted = 1, requests served = 2

With the change: header gone, ready() false, second request opens a new connection.

Client::decoder took the head by shared reference, so it could not remove the header and had no way to say the connection should not be reused. It now takes &mut and reports whether it removed a content-length; Client::parse clears keep_alive in that case. The existing client test asserted only .decode — the new assertions are the three-part form #4124 introduced on the server side.

Deliberately not changed: 1xx/204/304 and responses to HEAD return before the transfer-encoding branch, so a content-length there is left alone. On a HEAD response it is metadata about the body a GET would return rather than framing, and removing it would lose information.

cargo test --features full green, same 308 passing as master. cargo fmt --check clean. cargo clippy --features full -- -D warnings fails on unmodified master here too (unknown lint: clippy::unused_async_trait_impl, my clippy is 0.1.97), so I changed nothing for it.

AI disclosure: prepared with AI assistance (Claude Opus 5, claude-opus-5). The output above is from the commands as shown.

… transfer-encoding

The server side of this was fixed in hyperium#4124. The client side of the same
parse was left alone: Client::decoder took the head by shared reference,
so it could not remove the canceled content-length, and it had no way to
signal that the connection should not be reused.

Client::decoder now takes the head by mutable reference and reports
whether it removed a content-length, and Client::parse clears keep_alive
in that case.
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