Skip to content

trillium-http-v1.3.2

Choose a tag to compare

@github-actions github-actions released this 25 May 03:04
· 61 commits to main since this release

Changed

  • All protocol versions: Previously, when upgrading on the client or server, outbound bodies were intentionally dropped. As of this release, content-length is stripped and any body that has been set is sent off before transitioning to upgrade.

Fixed

  • HTTP/2 server: a bidirectional or upgraded stream (such as a gRPC streaming RPC or a WebSocket-over-HTTP/2 connection) was torn down as soon as the client half-closed its request side, even while the server was still streaming the response. The rest of the response and any trailers were dropped, surfacing to the client as a stream reset or broken-pipe error. The server now keeps its response side open until the response completes. Relatedly, a handler's writes to a stream the client had reset mid-flight were silently discarded; they now report a broken-pipe error so the handler can stop.
  • HTTP/3: reading a body (request bodies in the server role, response bodies in the client role) could hang or fail with a spurious UnexpectedEof when the body's first DATA frame had been buffered alongside the headers and was then read with a buffer smaller than a frame header — as happens reading a body one byte at a time. Bodies read with a larger buffer, or whose body arrived separately from the headers, were unaffected. These now decode correctly.
  • HTTP/2 server: an idle extended-CONNECT (RFC 8441) upgrade — or any response whose body source is not yet ready to produce data — could busy-spin the connection, burning CPU and flooding logs with drive trace lines while waiting for the next write. The connection now sleeps until there is work to do.
  • HTTP/2 client: a request could hang forever when the connection closed without delivering a response — a graceful GOAWAY, a peer FIN, or an I/O error — unless the server had explicitly reset that stream. In-flight requests (awaiting response headers, reading a response body, or writing to an upgraded stream) now surface a connection-aborted / broken-pipe error instead of hanging.

Security

  • HTTP/2 server: a peer could exhaust server memory by opening a header block (a HEADERS frame without END_HEADERS) and then sending an unbounded stream of CONTINUATION frames without ever ending it — the "CONTINUATION flood" (CVE-2024-27316 class). The cumulative compressed header block is now bounded by the advertised SETTINGS_MAX_HEADER_LIST_SIZE (HttpConfig::max_header_list_size, default 32 KiB); a block exceeding it closes the connection with GOAWAY(ENHANCE_YOUR_CALM) before decoding.
  • HTTP/2: a message whose content-length header disagreed with the actual length of its body was accepted rather than rejected — on the server for request bodies, and on the client for response bodies. A body longer than declared was silently truncated at the declared length; a shorter one was only caught if the body happened to be read to its end. The gap between a declared and actual body length is a request/response-smuggling / desync primitive, most concretely when the message is forwarded to an HTTP/1 peer whose parser trusts content-length. Both directions are now rejected with a stream error: a body that overruns its declared length the moment it does so, and a short one when the stream ends.