fix: strip connection-specific headers from HTTP/2 requests - #935
Open
lennartschoch wants to merge 1 commit into
Open
fix: strip connection-specific headers from HTTP/2 requests#935lennartschoch wants to merge 1 commit into
lennartschoch wants to merge 1 commit into
Conversation
RFC 9113 8.2.2 bans connection, keep-alive, proxy-connection, transfer-encoding and upgrade, and the h2 layer refuses to send a block containing one, so the request fails with protocol_error before it reaches the socket. They are legal in HTTP/1.1 and the caller cannot know which protocol ALPN picked, so drop them next to Host rather than failing requests that are valid for hackney's own API.
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.
Hit this moving an Elixir app onto hackney 4. As soon as ALPN picked h2, every request to one API started failing with
{error, protocol_error}and nothing reached the server.Turned out the client sets
Connection: keep-alivein its default headers, which is fine in HTTP/1.1 and banned in h2 (RFC 9113 §8.2.2). The h2 layer is doing the right thing here —validate_outbound_request/1rejects the header block and repliesprotocol_errorbefore anything is written. The problem is thatnormalize_headers/1only stripsHost, so the header gets that far in the first place.Since hackney picks the protocol itself via ALPN, the caller has no way to know which set of rules applies, so it can't really be the caller's job to leave these out.
Hostis already dropped there for the same kind of reason (:authoritycarries it), so this just extends it to the other five.TEis left alone since it's allowed with the valuetrailersand the h2 layer checks that separately.rebar3 eunitis green, 1099 tests. The three new ones intest/hackney_http2_connection_headers_tests.erlfail without the change with{error, protocol_error}— one forConnectionon its own, one for all five in mixed casing, and one checking ordinary headers still get through so the filter isn't over-eager.