Expand description
HTTP serve loop with connection limits (issue #3065).
serve replaces axum::serve. axum gives no access to the hyper
builder. Thus axum cannot set a header-read timeout, a header size limit
or an HTTP/2 stream limit. This loop applies HttpLimits from
[server.http]. With default limits it behaves like axum::serve.
§Timers
Each connection is in one of three phases:
- Head: the connection opened and no request arrived yet.
header_read_timeoutapplies (if it is not set,keep_alive_timeout). - Busy: at least one request is in flight. No timer applies. The request timeout layer limits handlers.
- Idle: no request in flight.
keep_alive_timeoutapplies.
In every phase, an open head also starts header_read_timeout, and
suspends the idle timer. The timer starts at the first byte of the head.
More bytes do not restart it, so a slowloris client cannot keep the
connection open. To find heads, the read path scans the client bytes:
- HTTP/1: a small framer skips bodies (
Content-Length, chunked). A head runs from its first byte to its blank line, also when it is pipelined behind another request. CRLF between messages does not open a head. - HTTP/2: a head is a header block (
HEADERSandCONTINUATIONframes, up to the payload of theEND_HEADERSframe). Control frames (for examplePING) do not open one.
The timers also run during a graceful drain.
§Drain of a fresh connection
A connection that has received no request is not closed at the drain signal. Its
request can be in flight, and a close would reset it. The server waits up
to FRESH_CONN_GRACE (2 s) for the first request, or until the head timer
ends. Then it starts the drain. Setup of an accepted connection (the
make-service) gets the same grace after a shutdown, so a stuck one cannot
hang the drain.
Structs§
- Http
Limits - Resolved
[server.http]limits.0in the config means “off”. - Incoming
Stream - One accepted connection, given to the make-service.
- Keep
Tunnel - Keeps an HTTP/2 WebSocket connection out of its idle timer.
Functions§
- serve
- Serve
make_serviceonlisteneruntilsignalresolves, then drain.