Changelog

View Source

All 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.0] - 2026-09-28

Added

  • Listener options h2_initial_window_size and h2_max_frame_size, aliases of the h2_settings keys
  • 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_policy and h2_stream_window_policy, credit policies for the HTTP/2 receive windows with the shapes eager, {threshold, N}, {delay, Ms} and never
  • The on_response shape of both credit policies, which sends the credit for a request ahead of the HEADERS of its {reply, _, _} response, and the listener option h2_credit_batch that batches the connection credit

Changed

  • Updates nhttp_lib reference
  • 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_settings accepts max_send_buffer and max_queued_streams, the bounds of the codec send queue. The server defaults both to infinity. 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_lib 1.1.1

[1.1.0] - 2026-09-10

Changed

  • Requires nhttp_lib 1.1.0
  • Socket re-arming for the next read is centralized. A setopts error on a peer that closed ends the HTTP/1.1, HTTP/2, and WebSocket loops as a normal close
  • The nhttp.http.request.duration metric records native time units. The consumer converts them

Fixed

[1.0.4] - 2026-08-24

Fixed

  • HTTP/1.1 connections no longer crash when the peer closes the socket. A setopts call 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_lib 1.0.4 for correct HTTP/1.1 Content-Length handling. An empty-body response now emits Content-Length: 0, a 1xx, 204, or 304 response emits no Content-Length field, and a 2xx response to a CONNECT request 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_size gives 1009, and other framing errors keep 1002. Before, every decode error gave 1002

Changed

  • Requires nhttp_lib 1.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 nquic library 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