Malachi.HTTP.Limits (malachi v0.22.7)

View Source

The request limits every HTTP listener on the node enforces, read from one set of configuration keys.

Two listeners parse HTTP today: the legacy dashboard (Malachi.Dashboard, by hand on :gen_tcp) and the console endpoint (Malachi.Console.Endpoint, on Bandit). Both take their header bounds and their read deadline from here, so an operator who tightens a limit tightens it on both, and the console cannot drift away from the bounds the dashboard's security suite pins down.

KeyDefaultBounds
:dashboard_max_header_count50header lines per request, repeats included
:dashboard_max_header_line_size10,000bytes in the request line and in each header line, at most 1 MiB
:dashboard_max_header_size32,768bytes of names plus values across all headers
:dashboard_recv_timeout_ms5,000the request line and the whole header block

The keys keep their dashboard_ prefix because the environment variables operators already set (MALACHI_DASHBOARD_MAX_HEADER_*) map to them.

Summary

Types

Header bounds: lines per request, bytes per line, and bytes of names plus values in total.

Functions

The header bounds. Read when a listener starts, so a bad value is reported once rather than on every request; an invalid value falls back to its default through Malachi.Config.checked/4.

Deadline, in milliseconds, for the request line and the whole header block together. Without it a client that connects and sends nothing pins a process and a socket indefinitely (slowloris), and a per-read timeout alone would let a client that sends one header just inside it hold the connection for as many reads as it is allowed headers. On the console it is also how long an idle keep alive connection is held.

Types

headers()

@type headers() :: %{count: pos_integer(), line: pos_integer(), total: pos_integer()}

Header bounds: lines per request, bytes per line, and bytes of names plus values in total.

Functions

headers()

@spec headers() :: headers()

The header bounds. Read when a listener starts, so a bad value is reported once rather than on every request; an invalid value falls back to its default through Malachi.Config.checked/4.

recv_timeout_ms()

@spec recv_timeout_ms() :: non_neg_integer()

Deadline, in milliseconds, for the request line and the whole header block together. Without it a client that connects and sends nothing pins a process and a socket indefinitely (slowloris), and a per-read timeout alone would let a client that sends one header just inside it hold the connection for as many reads as it is allowed headers. On the console it is also how long an idle keep alive connection is held.