feat(http1): add max_header_size limit for server and client by Aditya-9-6 · Pull Request #4183 · hyperium/hyper · GitHub
Skip to content

feat(http1): add max_header_size limit for server and client - #4183

Open
Aditya-9-6 wants to merge 1 commit into
hyperium:masterfrom
Aditya-9-6:feat/http1-max-header-size
Open

feat(http1): add max_header_size limit for server and client#4183
Aditya-9-6 wants to merge 1 commit into
hyperium:masterfrom
Aditya-9-6:feat/http1-max-header-size

Conversation

@Aditya-9-6

Copy link
Copy Markdown

Motivation

Resolves #3832.

Currently, HTTP/1 header size limits can only be indirectly bounded using max_buf_size. However, setting max_buf_size also restricts the maximum single read buffer for streaming request or response bodies. Furthermore, there was an existing TODO in proto/h1/conn.rs noting that h1_max_header_size should be wired up to the chunked decoder for trailers.

This PR adds explicit max_header_size(bytes) configuration options to both server::conn::http1::Builder and client::conn::http1::Builder.

Solution & Architecture

  • Server Builder (server::conn::http1::Builder):
    • Exposes pub fn max_header_size(&mut self, val: usize) -> &mut Self.
    • Configures the maximum total size of HTTP/1 request headers (request line + headers) in bytes.
    • When exceeded, the server responds with 431 Request Header Fields Too Large (RFC 6585 §5) and closes the connection.
  • Client Builder (client::conn::http1::Builder):
    • Exposes pub fn max_header_size(&mut self, val: usize) -> &mut Self.
    • Configures the maximum total size of HTTP/1 response headers (status line + headers) in bytes.
    • When exceeded, the client returns an error where error.is_parse_too_large() == true.
  • Early Enforcement:
    • Enforced in io::Buffered::parse_headers as bytes are read, preventing buffering unbounded amounts of header data.
    • Enforced in Server::parse / Client::parse against parsed_len to protect scenarios where a single read buffer already contains subsequent data.
  • Chunked Trailers:
    • Replaced the pre-existing // TODO: remove this when we land h1_max_header_size support placeholder in proto::h1::conn.rs (decode::Decoder::new) with the configured h1_max_header_size.

Verification

  • Unit test in src/proto/h1/role.rs:
    • test_h1_max_header_size: Tests exact boundary conditions on both server and client parsers.
  • Integration tests in tests/server.rs:
    • max_header_size_exceeded: Verifies server returns 431 Request Header Fields Too Large when request header size exceeds limit.
    • max_header_size_accepted: Verifies server accepts requests when within limit.
    • max_header_size_with_large_max_buf_size: Verifies max_header_size enforcement is decoupled from and strictly enforced even when max_buf_size is large.
  • Integration tests in tests/client.rs:
    • client_max_header_size_exceeded: Verifies client errors with is_parse_too_large() == true.
    • client_max_header_size_accepted: Verifies client successfully receives responses within limit.
  • All test suites passing (cargo test --lib --features full, cargo test --test server --features full, cargo test --test client --features full).

Adds max_header_size(val: usize) on both server and client HTTP/1 builders.
This allows configuring an explicit byte limit for request/response headers
(including the start line and chunked trailers).

When the limit is exceeded:
- On server: responds with 431 Request Header Fields Too Large and closes the connection.
- On client: returns a Parse::TooLarge error (is_parse_too_large).
- On chunked decoder: replaces existing TODO in proto/h1/conn.rs with the configured h1_max_header_size.

Closes hyperium#3832.
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.

Add HTTP/1 max header size limit

1 participant