fix: don't forward stale Content-Encoding/Content-Length to the client - #1
Open
IntenZe1337 wants to merge 1 commit into
Open
fix: don't forward stale Content-Encoding/Content-Length to the client#1IntenZe1337 wants to merge 1 commit into
IntenZe1337 wants to merge 1 commit into
Conversation
httpx transparently decompresses the upstream response body, so by the time
we build the Response the body is plaintext. Forwarding the upstream headers
verbatim via dict(response.headers) keeps Content-Encoding: gzip and the
compressed Content-Length, which describe a body that no longer exists.
Any client that sends Accept-Encoding: gzip then tries to gunzip plaintext
and fails. With curl this is CURLE_BAD_CONTENT_ENCODING (exit 61):
$ curl --compressed -sS http://localhost:8082/v1/messages \
-H 'content-type: application/json' \
-H 'x-api-key: ...' -H 'anthropic-version: 2023-06-01' \
-d '{"model":"...","max_tokens":16,"messages":[{"role":"user","content":"hi"}]}'
curl: (61) Error while processing content unencoding: invalid stored block lengths
Strip the hop-by-hop / transport-describing headers and let the ASGI server
compute correct values for the body actually sent. Streaming responses were
never affected; this covers the two non-streaming return paths
(/v1/messages and /v1/messages/count_tokens).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.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.
Problem
Non-streaming responses are returned with the upstream headers copied verbatim:
httpx transparently decompresses the response body, so by the time we build that
Responsethe content is already plaintext. Butdict(response.headers)still carriesthe upstream
Content-Encoding: gzipand the compressedContent-Length— headersthat describe a body which no longer exists.
Any client that sends
Accept-Encoding: gzipthen tries to gunzip plaintext and fails.Reproduction
CURLE_BAD_CONTENT_ENCODING, exit code 61. Without--compressedthe same requestsucceeds, which is what makes this easy to miss during manual testing — but most real
HTTP clients negotiate gzip by default.
Fix
Strip the transport-describing / hop-by-hop headers before forwarding and let the ASGI
server compute correct values for the body actually sent:
Applied to the two non-streaming return paths:
/v1/messagesand/v1/messages/count_tokens. Streaming responses build their headers explicitly and werenever affected.
connection,keep-aliveandtransfer-encodingare included because they areper-connection headers that must not be relayed across a proxy hop (RFC 9110 §7.6.1);
they were not the cause of the observed failure but belong in the same set.
Scope
20 lines added, 2 changed,
proxy.pyonly. No behaviour change for clients that do notrequest compression.