Skip to content

http-netty: document and test HTTP/2 header-name validation#3555

Open
bryce-anderson wants to merge 1 commit into
apple:mainfrom
bryce-anderson:bl_anderson/h2-non-token-chars
Open

http-netty: document and test HTTP/2 header-name validation#3555
bryce-anderson wants to merge 1 commit into
apple:mainfrom
bryce-anderson:bl_anderson/h2-non-token-chars

Conversation

@bryce-anderson

Copy link
Copy Markdown
Contributor

Motivation

HTTP/2 header-name validation happens across two layers and is easy to misread. ServiceTalkHttp2Headers (the Http2Headers wrapper) only enforces the HTTP/2 lower-case rule, while the RFC 7230 token grammar is enforced one layer down by the underlying HttpHeaders via HeaderUtils.validateToken. Both are gated on the same HttpHeadersFactory.validateNames() flag. The split is correct but undocumented, so the wrapper looks like it under-validates when it does not.

Modifications

  • Comment-only changes describing the two-layer split on ServiceTalkHttp2Headers.HTTP2_NAME_VALIDATOR, the outbound validateNames=false opt-out in h1HeadersToH2Headers, and the shared-flag wiring in OptimizedHttp2FrameCodecBuilder.
  • Add ServiceTalkHttp2HeadersTest: pins which layer rejects what — the wrapper rejects upper-case, the underlying rejects non-token / non-ASCII names, valid lower-case tokens are accepted, and validation is skipped when disabled.
  • Add H2PriorKnowledgeFeatureParityTest.h2ServerResetsStreamForInvalidHeaderName: a raw peer puts invalid field-names on the wire and the server resets the stream with PROTOCOL_ERROR. Extract the existing wire harness into a helper.

Result

The two-layer header-name validation is documented and covered end-to-end, so a future change that weakens either layer is caught by tests.

#### Motivation

HTTP/2 header-name validation happens across two layers and is easy to misread.
`ServiceTalkHttp2Headers` (the `Http2Headers` wrapper) only enforces the HTTP/2
lower-case rule, while the RFC 7230 token grammar is enforced one layer down by
the underlying `HttpHeaders` via `HeaderUtils.validateToken`. Both are gated on
the same `HttpHeadersFactory.validateNames()` flag. The split is correct but
undocumented, so the wrapper looks like it under-validates when it does not.

#### Modifications

- Comment-only production changes describing the two-layer split on
  `ServiceTalkHttp2Headers.HTTP2_NAME_VALIDATOR`, the outbound
  `validateNames=false` opt-out in `h1HeadersToH2Headers`, and the shared-flag
  wiring in `OptimizedHttp2FrameCodecBuilder`. No logic changed.
- Add `ServiceTalkHttp2HeadersTest`: pins which layer rejects what — the wrapper
  rejects upper-case, the underlying rejects non-token / non-ASCII names, valid
  lower-case tokens are accepted, and validation is skipped when disabled.
- Add `H2PriorKnowledgeFeatureParityTest.h2ServerResetsStreamForInvalidHeaderName`:
  a raw peer puts invalid field-names on the wire and the server resets the
  stream with `PROTOCOL_ERROR`. Extract the existing wire harness into a helper.

#### Result

The two-layer header-name validation is documented and covered end-to-end, so a
future change that weakens either layer is caught by tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant