v1.1.0
Added
nhttp_h1:prepare_headers/1validates a header list once and returns a
block thatencode_request/2andencode_response/2reusenhttp_h1:encode_trailers/1andnhttp_h1:encode_response_head/4nhttp_h2:stream_stats/1reports the active, peer-opened, and peer-reset
stream countsmax_reset_streamsandmax_continuation_framesint:nhttp_h2:settings/0.
Both are local bounds and go on no wire.max_continuation_framesdefaults
to a value derived frommax_header_list_sizet:nhttp_ws_frame:frame_limits/0and the capped arities
nhttp_ws_frame:decode/2,decode_raw/3, anddecode_unmasked/2nhttp_headers:validate_field_name/1,validate_field_value/1,
lower_field_name/1,name_eq/2,is_token/1, andis_tchar/1
Changed
nhttp_h1:encode_request/1,2andnhttp_h1:encode_response/1,2return
{ok, iolist()} | {error, t:nhttp_h1:encode_error/0}. They returned
iolist()beforenhttp_cookie:encode_cookie/1andnhttp_cookie:encode_set_cookie/1return
{ok, binary()} | {error, _}, and the error names the class of the
violationnhttp_msg:build_response/2returns
{ok, response()} | {error, invalid_status | missing_status}nhttp_hpack:decode/2,3answers{invalid_field, Reason, State}, a shape
apart from the{error, Reason}of a decompression failure.Statecarries
every dynamic table update that the block asks for (RFC 9113 Section 4.3)nhttp_h1andnhttp_cookiescan with patterns that-on_loadcompiles
intopersistent_term, and the encode and parse paths build no intermediate
binary
Security
- Refuse a field name that is not a token, and a field value that carries CR,
LF, NUL, another control byte, or0x7F, at the HTTP/1.1 encoder. The
message is refused whole (RFC 9110 Sections 5.5 and 5.6.2, RFC 9112 Section
11.1). Response splitting and request smuggling (CVE-2020-11709,
CVE-2023-26130, CVE-2025-0825, CVE-2026-21428, CVE-2026-45372) - Validate a cookie name, a cookie value, a
Path, and aDomainagainst the
RFC 6265 Section 4.1.1 grammar on encode. No value is stripped, quoted, or
truncated (CVE-2020-11709, CVE-2023-26130, CVE-2025-0825, CVE-2026-21428,
CVE-2026-45372) - Read every literal field name and every literal field value in the HPACK and
the QPACK decoder. An uppercase name, an invalid octet, an interior colon, or
a value with leading or trailing whitespace is a stream error of type
PROTOCOL_ERROR on HTTP/2 and H3_MESSAGE_ERROR on HTTP/3 (RFC 9113 Section
8.2.1, RFC 9114 Section 4.1.2) - Combine every
Transfer-Encodingfield line into one coding list, and accept
the message only when that list holdschunkedonce, as the final coding
(RFC 9112 Sections 6.1 and 6.3). Refuse a chunk that does not end with CRLF
asincomplete_chunk, and refuse aContent-Lengthvalue that is not a run
of digits (CVE-2026-34441, CVE-2026-45352, CVE-2026-46527) - Refuse a declared WebSocket payload length above
max_frame_sizeas
{error, {frame_too_large, DeclaredLength}}, before the payload is buffered
(RFC 6455 Section 10.4).nhttp_wscaps at its maximum message size
(CVE-2025-46728, CVE-2025-53629) - Refuse a byte that follows a complete gzip or deflate stream as
{error, trailing_data}(CVE-2026-22776, CVE-2026-28435) - Count the streams that the peer opens and resets, and fail the connection
with ENHANCE_YOUR_CALM abovemax_reset_streams(CVE-2023-44487). Bound the
number of CONTINUATION frames in one field block (CVE-2026-29076) nhttp_msg:build_response/2never raises on peer input. A missing or
malformed:statusis a stream error (CVE-2026-31870)
Full Changelog: v1.0.5...v1.1.0