Repository navigation
Conversation
…whitespace
Motivation:
RFC 9113 8.2.1 makes an HTTP/2 message malformed when a field name contains an
uppercase character or a field value starts or ends with SP or HTAB. Pekko HTTP accepted
both: regular fields are handed to the HTTP/1.1 header-line parser, which matches names
case-insensitively and trims the value, so the message was silently normalised instead of
rejected. Other HTTP/2 implementations (nghttp2, netty for names) reject them, so two hops
can disagree about the same field.
On the client, a field rejected in HeaderDecompression left the response with no headers
and was reported as a missing ':status' rather than as what was wrong.
Modification:
- HeaderDecompression rejects an uppercase field name and a value with leading or
trailing SP/HTAB, next to the existing NUL/CR/LF check. The messages from this stage
drop the "Malformed request:" prefix, since it decodes responses on the client too.
- ResponseParsing reports a header error from decompression as
"Malformed response: <reason>".
- Lowercase the incidental uppercase names ("Foo", "Connection", "TE") in RequestParsingSpec
tests that check other rules, and let the ':authority'/':path' tests that pass
whitespace-only or whitespace-terminated values accept the earlier field-check message.
- Add a ResponseParsingSpec for the client side.
Result:
Requests with such fields get a 400 for the stream; responses with them fail with a
protocol error naming the field problem. Pekko HTTP's own client and server always render
lowercase names, so traffic between them is unaffected.
Tests:
- Without the main change the new RequestParsingSpec uppercase/whitespace tests and the
ResponseParsingSpec rejection tests fail
- sbt http2-tests/test: 393 passed
- sbt http-core/mimaReportBinaryIssues and scalafmt checks: pass
References:
None - follow-up to apache#1341
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.
Motivation
RFC 9113 §8.2.1 says an HTTP/2 message is malformed if a field name contains an uppercase character, or if a field value starts or ends with SP or HTAB. Pekko HTTP accepted both. Regular fields are handed to the HTTP/1.1 header-line parser, which matches names case-insensitively and trims the value, so the message was silently normalised instead of rejected. Other HTTP/2 implementations reject these (nghttp2 rejects both; netty rejects uppercase names), so two hops can disagree about the same field.
On the client, a field rejected during decompression left the response with no headers. The failure was then reported as a missing
:statusrather than as what was actually wrong.This is behaviour tightening, which suits a major release. Pekko HTTP's own client and server always render lowercase names and never pad values, so traffic between them is unaffected.
Modification
HeaderDecompressionrejects an uppercase field name and a value with leading or trailing SP/HTAB, next to the existing NUL/CR/LF check. Internal whitespace and empty values are still accepted. This stage also decodes responses on the client, so its messages drop the "Malformed request:" prefix.ResponseParsingreports a header error from decompression asMalformed response: <reason>.RequestParsingSpec, lowercase the incidental uppercase names (Foo,Connection,TE) in tests of other rules. Let the:authority/:pathtests that pass whitespace-only or whitespace-terminated values also accept the new field-check message; those values are still rejected.RequestParsingSpeccases: uppercase names, leading/trailing SP/HTAB in values, and acceptance of internal whitespace and empty values.client/ResponseParsingSpec: a valid response parses; an uppercase name, surrounding whitespace, and CR/LF each fail with a message naming the problem.Result
Tests
RequestParsingSpecand the three rejection tests inResponseParsingSpecfailsbt http2-tests/test: 393 passedsbt http-core/mimaReportBinaryIssues: passsbt http-core/scalafmtCheckAll http2-tests/Test/scalafmtCheck: passReferences
None - follow-up to #1341