pub struct ServerSection {Show 19 fields
pub host: String,
pub port: u16,
pub max_body_bytes: usize,
pub request_timeout_ms: u64,
pub header_read_timeout_ms: u64,
pub max_headers: usize,
pub max_path_segments: usize,
pub ws_max_frame_bytes: usize,
pub keep_alive_ms: u64,
pub backlog: u32,
pub shutdown_timeout_ms: u64,
pub ws_max_message_bytes: usize,
pub path_policy: PathPolicy,
pub h2_max_header_list_size: u32,
pub h2_max_concurrent_streams: u32,
pub ws_idle_timeout_ms: u64,
pub max_connections: usize,
pub max_tls_handshakes: usize,
pub tls_handshake_timeout_ms: u64,
}Expand description
The [server] configuration table.
Every field has a default (see ServerSection::default), so a partial
[server] table is valid.
Fields§
§host: StringBind address host (default "127.0.0.1").
port: u16Bind port (default 8080).
max_body_bytes: usizeMaximum accepted request body size in bytes (default 1 MiB). Larger
bodies are rejected with 413 Payload Too Large.
A body whose Content-Length exceeds this is refused before the request
is dispatched, so a handler that never reads the body cannot serve one
anyway. A chunked body declares no length, so it is bounded as it is
read — which means a handler that ignores a chunked body will not notice
the cap. Reject on Transfer-Encoding explicitly if that matters.
Raise request_timeout_ms alongside it: the
per-request timeout spans the upload, so a generous size cap paired with
a short timeout rejects large-but-legitimate transfers part-way through.
request_timeout_ms: u64Per-request timeout in milliseconds (default 30000). 0 disables the
timeout.
It bounds the whole exchange, including reading the request body.
Bodies stream, so they are read inside the handler rather than before
it, and a slow upload consumes this budget however small it is. Raising
max_body_bytes therefore means raising this in
step: a 100 MiB cap with a 30-second timeout rejects any client slower
than ~3.4 MiB/s, mid-transfer, with 408.
header_read_timeout_ms: u64How long a connection may take to send its complete header block, in
milliseconds (default 10000). 0 disables it.
This is the slow-loris defence: without it a client can hold a connection open indefinitely by dribbling one header byte at a time, because the per-request timeout does not start until there is a request.
It covers all three phases of a connection, by different means.
Before either protocol exists, the server is still reading up to the 24 bytes of the HTTP/2 preface to find out which one to speak, and neither mechanism below has been created yet. A connection that does not get as far as choosing a protocol within this deadline is closed — which is what bounds a peer that connects and then sends nothing at all.
HTTP/1 then gets a literal deadline on the header block. HTTP/2 has no equivalent — a header block arrives as frames on an already-open connection — so the same value drives a keep-alive PING and the deadline for its acknowledgement, which answers the equivalent question of whether the peer is still there. A stalled h2 peer is therefore dropped within roughly twice this value, and a live one with nothing to say answers the ping and stays: once a protocol has been negotiated this deadline no longer applies, so an idle-but-responsive client is not bound by it.
max_headers: usizeMaximum number of headers accepted on a request (default 100).
max_path_segments: usizeMaximum path segments accepted before a request is rejected with 414
(default 64).
The router walks segments recursively with backtracking, so path depth is a stack-depth question. hyper bounds the request line, which bounds this in practice, but the bound should be Churust’s own and stated rather than inherited by accident.
ws_max_frame_bytes: usizeMaximum WebSocket frame size in bytes (default 1 MiB). Requires the
ws feature.
keep_alive_ms: u64How long an idle connection is kept open for reuse, in milliseconds
(default 75000). 0 disables keep-alive: answer and close.
Idle means no request in flight — a handler slower than this is busy, not idle, and its connection is left alone. The timer restarts when a request finishes.
backlog: u32Listen backlog: connections the kernel may queue before the accept loop
reaches them (default 1024).
shutdown_timeout_ms: u64How long graceful shutdown waits for in-flight requests to finish, in
milliseconds (default 30000). 0 waits indefinitely.
Without a bound, one slow request delays shutdown forever, which in a container means being killed rather than exiting cleanly.
ws_max_message_bytes: usizeMaximum reassembled WebSocket message size in bytes (default 4 MiB).
Requires the ws feature.
Separate from the frame cap because a peer can send many small continuation frames that reassemble into one enormous message.
path_policy: PathPolicyWhat to do with a non-canonical path spelling (default "strict").
One of "strict", "redirect" or "collapse". See
PathPolicy.
h2_max_header_list_size: u32Maximum size of a received HTTP/2 header block, in bytes (default
16384).
The HTTP/2 counterpart of max_headers, which
configures HTTP/1 only: h2 has no header count, it has an encoded
size. Exceeding it is refused at the protocol level.
h2_max_concurrent_streams: u32Maximum concurrent HTTP/2 streams per connection (default 200). 0
removes the limit.
One h2 connection multiplexes many requests, so without this a single connection is an unbounded amount of concurrent work — the shape behind the HTTP/2 stream-flood denial-of-service family. hyper’s own docs encourage setting an explicit limit rather than inheriting its default.
ws_idle_timeout_ms: u64How long an upgraded WebSocket may sit with no traffic in either
direction before it is closed, in milliseconds (default 300000, five
minutes). 0 disables the bound. Requires the ws feature.
An upgraded socket holds a connection permit for its whole life, and
none of the HTTP-level bounds survive the upgrade —
header_read_timeout_ms applies before
there is a WebSocket and request_timeout_ms
wraps a request that has already completed. Without this, a peer that
completes the handshake and then says nothing pins a permit until the
process restarts.
max_connections: usizeMaximum simultaneously served connections (default 25000). 0 means
unlimited.
The backlog bounds what the kernel queues; this bounds what the process accepts. Without it, memory and file descriptors are limited only by what the OS will hand out, and the failure mode is the whole process dying rather than new connections waiting.
max_tls_handshakes: usizeMaximum TLS handshakes in progress at once (default 256). 0 means
unlimited. Requires the tls feature.
Much smaller than max_connections on purpose:
a handshake is asymmetric work — cheap to ask for, expensive to answer —
so it needs its own, tighter bound.
tls_handshake_timeout_ms: u64How long a TLS handshake may take before the connection is dropped, in
milliseconds (default 10000). 0 disables the bound.
header_read_timeout_ms cannot cover
this: before the handshake completes there is no HTTP layer to time out.
Without it, a client that completes the TCP handshake and then sends one
byte per minute holds a connection open indefinitely.
The clock starts when the connection is accepted, so it covers waiting
for a max_tls_handshakes permit as well as
the handshake itself. That is what makes it a bound on how long a peer
can hold a connection permit: timing only the handshake would let a
queue of stalled peers expire a permit’s worth at a time while the rest
waited unbounded. A consequence worth knowing is that under genuine
handshake overload a legitimate client can be dropped while still
queued — the alternative is holding its connection slot instead.
Trait Implementations§
Source§impl Clone for ServerSection
impl Clone for ServerSection
Source§fn clone(&self) -> ServerSection
fn clone(&self) -> ServerSection
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more