Skip to content

feat: validate connection-specific headers and concatenate cookies (RFC 9114 §4.2, §4.2.1) - #364

Open
bhargavamakwana wants to merge 1 commit into
hyperium:masterfrom
bhargavamakwana:feat/validate-connection-headers-and-cookies
Open

bhargavamakwana wants to merge 1 commit into
hyperium:masterfrom
bhargavamakwana:feat/validate-connection-headers-and-cookies

Conversation

@bhargavamakwana

Copy link
Copy Markdown

Summary

This PR implements RFC 9114 compliance for connection-specific field sections (§4.2), the TE header field (§4.2), cookie line concatenation (§4.2.1), and pseudo-header restrictions in trailers (§4.3).

Resolves two pending Duvet tracking items:

  • .duvet/todos/rfc9114/4.2.toml
  • .duvet/todos/rfc9114/4.2.1.toml

Motivation & Background

In HTTP/3, stream multiplexing is pushed down to QUIC, rendering HTTP/1.x connection management mechanisms obsolete and invalid:

  1. RFC 9114 §4.2 (Connection-Specific Fields):

    "An endpoint MUST NOT generate an HTTP/3 field section containing connection-specific fields; any message containing connection-specific fields MUST be treated as malformed."

    Previously, Field::parse() and outgoing header builders (Header::request, Header::response, Header::trailer) permitted connection-specific headers (connection, keep-alive, proxy-connection, transfer-encoding, upgrade) without rejection.

  2. RFC 9114 §4.2 (The TE Header):

    "The only exception to this is the TE header field, which MAY be present in an HTTP/3 request header; when it is, it MUST NOT contain any value other than 'trailers'."

    te was previously treated as a standard header, permitting invalid values (e.g. gzip) and invalid contexts (responses/trailers).

  3. RFC 9114 §4.2.1 (Field Compression - Cookie Folding):

    "If a decompressed field section contains multiple cookie field lines, these MUST be concatenated into a single byte string using the two-byte delimiter of '; ' (ASCII 0x3b, 0x20)..."

    Header::try_from() previously retained duplicate cookie lines as separate entries in HeaderMap rather than folding them with ; .

  4. RFC 9114 §4.3 (Trailers):

    "Pseudo-header fields MUST NOT appear in trailer sections."

    Incoming trailers were not checked for pseudo-headers.


Detailed Changes

  • h3/src/proto/headers.rs:
    • Inbound validation in Field::parse():
      • Rejects connection, keep-alive, proxy-connection, transfer-encoding, and upgrade with HeaderError::ConnectionSpecificHeader.
      • Validates that te contains only 'trailers' (ignoring ASCII whitespace and case), returning HeaderError::InvalidTeHeader otherwise.
    • Outbound validation:
      • Updated Header::request(), Header::response(), and Header::trailer() to validate fields and return Result<Self, HeaderError> to enforce the "MUST NOT generate" requirement.
    • Contextual TE restriction:
      • Header::into_response_parts() and Header::into_trailer_parts() reject te if present in responses or trailers.
    • Cookie concatenation:
      • In Header::try_from(), multiple Cookie headers are automatically concatenated into a single value using ; .
    • Trailer validation:
      • Added Header::into_trailer_parts(), ensuring trailer sections contain zero pseudo-headers and no illegal connection fields.
    • Unit Tests:
      • Added rejects_connection_specific_headers()
      • Added validates_te_header()
      • Added concatenates_multiple_cookie_headers()
      • Added rejects_pseudo_headers_in_trailers()
  • h3/src/server/stream.rs:
    • Propagates HeaderError from Header::response() in send_response() as StreamError with code H3_MESSAGE_ERROR.
  • h3/src/connection.rs:
    • Decoded trailers now pass through Header::into_trailer_parts(), rejecting malformed trailers with H3_MESSAGE_ERROR.
    • Propagates HeaderError from Header::trailer() in send_trailers().
  • Duvet Specification Compliance:
    • Removed resolved .duvet/todos/rfc9114/4.2.toml and .duvet/todos/rfc9114/4.2.1.toml.
    • Updated .duvet/snapshot.txt: requirements transitioned from todo to [implementation,test].

Verification & Testing

  • Unit & Integration Tests:

    • All 234 tests pass cleanly (cargo test --workspace).
  • Lints:

    • cargo clippy --workspace --all-targets reports 0 warnings on modified code.
  • Duvet Report:

    • duvet report verified: 148 sources scanned, 570 citations parsed, with 0 regressions.

…kies

Enforces RFC 9114 §4.2, §4.2.1, and §4.3 requirements on HTTP/3 field sections:

- RFC 9114 §4.2: Treat field sections containing connection-specific headers
  ('connection', 'keep-alive', 'proxy-connection', 'transfer-encoding', 'upgrade')
  as malformed, and prevent generating them on outgoing headers.
- RFC 9114 §4.2: Reject 'te' header unless it is on a request and its value
  is 'trailers'.
- RFC 9114 §4.2.1: Automatically concatenate multiple decoded 'cookie' lines
  into a single byte string using '; '.
- RFC 9114 §4.3: Reject pseudo-headers appearing in trailer sections.
- Update duvet tracking: resolve todos in 4.2.toml and 4.2.1.toml, updating
  snapshot to [implementation,test].
- Add unit tests covering all forbidden connection headers, valid and invalid
  TE cases, cookie folding, and trailer pseudo-headers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant