Changelog
View SourceAll notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.2.1] - 2026-09-30
Changed
- Requires
nhttp_lib1.2.1
Fixed
- A
{stream, Spec, State}result with an invalidSpecon HTTP/2 ended the whole connection. The server now resets only that stream
[1.2.0] - 2026-09-28
Added
- Listener options
h2_initial_window_sizeandh2_max_frame_size, aliases of theh2_settingskeys - Listener option
h2_response_delay, a fixed or uniform delay before the response headers of a{reply, _, _}result on HTTP/2 - Listener options
h2_connection_window_policyandh2_stream_window_policy, credit policies for the HTTP/2 receive windows with the shapeseager,{threshold, N},{delay, Ms}andnever - The
on_responseshape of both credit policies, which sends the credit for a request ahead of the HEADERS of its{reply, _, _}response, and the listener optionh2_credit_batchthat batches the connection credit
Changed
- Updates
nhttp_libreference - Response bodies, producer chunks and WebSocket frames on HTTP/2 go through the codec send queue. The server keeps no remainder buffer of its own, and one connection grant reaches every blocked stream, one frame per stream per turn
- Every RST_STREAM the server sends goes through the codec, which closes the stream and purges the octets it holds for it
h2_settingsacceptsmax_send_bufferandmax_queued_streams, the bounds of the codec send queue. The server defaults both toinfinity. A response body, producer chunk or WebSocket frame that the bound refuses ends its stream with RST_STREAM(ENHANCE_YOUR_CALM). A producer sees{error, closed}and a WebSocket session closes with{transport, send_buffer_full}
Fixed
- A WebSocket-over-HTTP/2 frame that outran the send window was dropped without a record
- One large response was able to take a whole connection credit ahead of smaller ones
- The NO_ERROR RST_STREAM that asks a client to stop sending a request body went out before the response was complete, and the buffered body then followed it on a closed stream (RFC 9113 Section 5.1 and Section 8.1)
[1.1.1] - 2026-09-10
Changed
- Requires
nhttp_lib1.1.1
[1.1.0] - 2026-09-10
Changed
- Requires
nhttp_lib1.1.0 - Socket re-arming for the next read is centralized. A
setoptserror on a peer that closed ends the HTTP/1.1, HTTP/2, and WebSocket loops as a normal close - The
nhttp.http.request.durationmetric records native time units. The consumer converts them
Fixed
nhttp:start_error/0includes{already_started, pid()}
[1.0.4] - 2026-08-24
Fixed
- HTTP/1.1 connections no longer crash when the peer closes the socket. A
setoptscall that gives an error now closes the connection normally. A body read that gives an error tells the handler that the peer closed the connection
[1.0.3] - 2026-08-20
Changed
- Requires
nhttp_lib1.0.4 for correct HTTP/1.1Content-Lengthhandling. An empty-body response now emitsContent-Length: 0, a 1xx, 204, or 304 response emits noContent-Lengthfield, and a 2xx response to aCONNECTrequest can suppress it (RFC 9110 Section 8.6)
[1.0.2] - 2026-08-13
Added
- Support for Erlang/OTP 29.
[1.0.1] - 2026-08-12
Fixed
- WebSocket fragmented messages on HTTP/1.1. The connection keeps decoder state across reads, so a message split over several frames is reassembled and delivered once (RFC 6455 section 5.4)
- WebSocket CLOSE codes for decode errors. A text payload or CLOSE reason that is not valid UTF-8 gives 1007, a message over
max_message_sizegives 1009, and other framing errors keep 1002. Before, every decode error gave 1002
Changed
- Requires
nhttp_lib1.0.3 for the stateful frame decoder and incremental UTF-8 validation
Added
- WebSocket RFC 6455 compliance tests with Autobahn. Run them with
make ws-compliance
[1.0.0] - 2026-06-01
Initial public release.
Added
- HTTP/1.1 and HTTP/2 server with automatic protocol selection via TLS ALPN (RFC 9112, RFC 9113)
- HTTP/3 server over QUIC via in-process
nquiclibrary mode (RFC 9114) - Handler behaviour (
nhttp_handler) with a small callback set for request handling, streaming, and WebSocket sessions - WebSocket support across HTTP/1.1, HTTP/2, and HTTP/3 with one callback set (RFC 6455, RFC 8441, RFC 9220)
- Streaming responses via producer funs with end-to-end backpressure
- Streaming request bodies with handler-driven backpressure
- Server-Sent Events helpers (
nhttp_sse) - CORS preflight and response header helpers (
nhttp_cors) - Response compression (gzip / deflate) with MIME-aware defaults
- PROXY protocol v1/v2 for HAProxy / AWS NLB deployments
- SNI with static lookup table and dynamic callback
- OpenTelemetry spans and metrics (opt-in)
- Graceful shutdown with connection draining
- One process per connection, with HTTP/2 and HTTP/3 streams multiplexed inside it
- Per-stream handler workers on HTTP/2 to isolate slow handlers