pub const HEADERS_BUFFER_BUDGET: usize = _; // 1_048_576usizeExpand description
Most encoded frame payload one connection may hold buffered at once, in bytes (D77).
MAX_FIELD_SECTION_SIZE bounds one frame; this bounds their sum, and the
two are reached by different peers. A client held to the per-frame bound may
still open every request stream its transport parameters allow – 1024 by
default – announce a 64 KiB HEADERS frame on each and stop one byte short
of finishing any of them. Nothing in that is a rule broken on any single
stream, and the frames are held because they cannot be acted on piecewise:
64 MiB of a connection’s memory, from a peer that has not authenticated, for
as long as the transport is willing to call it alive, and available again
the moment the streams are reset. Multiplied by limits.max_connections it
is the whole of the machine. D76 bounds how long one stream may wait; this
bounds how much waiting costs.
A megabyte is sixteen frames of the largest size this server will buffer at all, and some four thousand of the size a real one is – a CONNECT request carrying Basic credentials is under 300 bytes, so all 1024 request streams the transport allows could be mid-HEADERS at once and still be using a tenth of this.
The exact boundary is worth stating, because it is not “a client that
finishes what it starts”: what is counted is the announced length of the
frames being buffered at one moment, so sixteen concurrent field sections
of the largest advertised size fill it and the seventeenth does not fit –
whether or not every one of them is completed a moment later. A peer that
reaches it loses that one request, which is answered with 431 and stopped
(frame::BufferBudget::charge); the connection and every tunnel on it carry
on. Bounding a moment rather than a rate is what makes the value a constant
here rather than a knob in [limits]: it is a ceiling on memory, and the
machine’s is not configurable either.
The peer’s control stream is not counted here. There is one of it per
connection and it buffers one frame at a time, so frame::MAX_BUFFERED_FRAME
bounds it on its own – and a peer that had filled this budget with request
streams must not thereby have its own SETTINGS or GOAWAY refused, since
nothing on that stream can be refused stream by stream.
The unit is encoded octets as they arrived, the same count
frame::MAX_BUFFERED_FRAME applies per frame – not RFC 9114 §4.2.2’s
field-section size, which is what MAX_FIELD_SECTION_SIZE measures.