Skip to content

trillium-http-v1.3.5

Choose a tag to compare

@github-actions github-actions released this 05 Jun 18:26
· 18 commits to main since this release

The theme of this release is protocol correctness / conformance, with a focus on http/1.x.

Added

  • Headers::content_length() parses the Content-Length header into an Option<u64>, accepting
    only a single run of ASCII digits (rejecting a leading +/-, which u64::from_str would
    otherwise accept, as well as multi-value, empty, and overflowing values). Prefer it over
    get_str(ContentLength).and_then(|c| c.parse().ok()).

Changed

  • The HTTP/1.x request parser is now trillium's own implementation; the httparse dependency is
    dropped and the parse cargo feature (which previously selected it) is retained as a no-op. The
    new parser is stricter — it closes the conformance and security gaps below — but against
    well-formed clients there is no observable difference.

Security

  • HTTP/1.x request smuggling: a malformed Content-Length was previously coerced to a zero-length
    body, leaving the declared bytes unread in the buffer. Obs-fold header continuations, control
    characters in header values and request targets, non-token header names, and malformed chunk
    framing were also accepted. All are now rejected, closing request-smuggling and parser-differential
    vectors.
  • HTTP/1.1 Host: a request with no Host, more than one, or a Host containing userinfo, a path,
    whitespace, or other illegal content is now rejected rather than routed.

Fixed

  • Absolute-form request targets (GET http://example.com/path) now route correctly; previously the
    entire URI was treated as the request path.
  • A request carrying both an authority (:authority or absolute-form) and a Host that differ only
    by default port — e.g. example.com:443 vs example.com — is no longer spuriously rejected; the
    two are compared under scheme-based normalization (all three protocols).
  • A chunked request body terminated by a bare LF after the last chunk no longer hangs the connection.
  • Malformed HTTP/1.x requests now get a 400 (or 501 for an unrecognized method) before the
    connection closes, instead of being dropped without a response. An unhandled CONNECT now defaults
    to 501 rather than 404.
  • A Connection: close token split across multiple Connection header lines now closes the
    connection as requested; previously the multi-line value was missed and the connection was kept
    alive.
  • HTTP/2 and HTTP/3 now reject a malformed Content-Length instead of coercing it to a body length:
    a malformed request earns RST_STREAM(PROTOCOL_ERROR) (h2) / H3_MESSAGE_ERROR (h3), and a
    malformed response on the client side earns RST_STREAM(PROTOCOL_ERROR) (h2). Previously such a
    value was silently treated as "no declared length," skipping the content-length / DATA
    cross-check.