feat: implement hop-by-hop header stripping for compliance with HTTP standards#583
Draft
feat: implement hop-by-hop header stripping for compliance with HTTP standards#583
Conversation
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
Backends that advertise HTTP/2 via ALPN (e.g. Tomcat on port 8443) returned HTTP/2 responses containing connection-specific headers such as
Keep-Alive. Netty's strict H2 stream decoder rejected these, producing:and causing 503s for every request routed to those backends. This violates RFC 9113 §8.2.2, which forbids connection-specific headers in HTTP/2.
The underlying cause was that
ProxyRequestsManagerwas forwarding client and backend headers verbatim, without stripping the hop-by-hop headers that a reverse proxy must not propagate between connections, as required by RFC 2616 §13.5.1 and RFC 7230 §6.1.Solution
Add
HttpUtils.stripHopByHopHeaders(), which removes the standard hop-by-hop set (Connection,Keep-Alive,Proxy-Authenticate,Proxy-Authorization,TE,Trailer,Upgrade,Proxy-Connection) plus any headers dynamically nominated via theConnectionheader value (RFC 7230 §6.1). Call it inProxyRequestsManagerin both directions: on the outgoing request copy before forwarding to the backend, and on the backend response headers before forwarding to the client.Transfer-Encodingis intentionally excluded from the stripped set: Reactor Netty's H2 codec enforces its removal at the wire level (RFC 9113 §8.2.2), and stripping it in Carapace would break HTTP/1.1 chunked proxying.