Download Latest Version 4.10.2 source code.zip (595.6 kB)
Home / 4.10.2
Name Modified Size InfoDownloads / Week
Parent folder
4.10.2 source code.tar.gz 2026-11-10 484.6 kB
4.10.2 source code.zip 2026-11-10 595.6 kB
README.md 2026-11-10 4.1 kB
Totals: 3 Items   1.1 MB 1

Fixed

  • Closing a connection whose server accepted the request but never answered could hang: close waited for the pending read to end, which on a pooled connection was never. close now returns within about a second (#996).
  • A request whose caller was killed while it waited for a pooled connection could keep its per-host slot forever. After enough such deaths (50 by default) every later request to that host failed with checkout_timeout until the node restarted. The slot is now released (#974).
  • A request that gave up waiting for a pooled connection (checkout_timeout) could still be served later by the pool: it opened or reserved a connection nobody used, and freed a per-host slot twice, which let more requests than max_per_host run against that host. The pool now skips requests whose caller has stopped waiting.
  • Opening several HTTPS connections to the same host at once could make a few of them fail with bad_record_mac when TLS 1.3 session resumption was on (the default). Erlang's TLS client could offer the same session ticket on two connections at once. Only one new connection per host now resumes a session at a time; the others do a full handshake (#995).
  • Socket options set in connect_options, such as {nodelay, true}, were lost on pooled connections: a request could be served a connection opened without them, including the ones the pool opens ahead of time. Pooled HTTP/1.1 and shared HTTP/2 connections are now only reused by requests with the same socket options, and the pool opens connections ahead of time with them. Requests without connect_options share connections as before (#970).
  • Through an HTTP CONNECT or SOCKS5 proxy, and on WebSocket connections, most socket options set in connect_options were dropped: only a few (nodelay, linger, send_timeout, raw, inet6) reached the socket, and a WebSocket through a proxy used none of them. All socket options now apply. Options hackney needs to read the socket itself, such as active or packet, are still ignored (#970).
  • HTTP/3 connections ignored the socket options in connect_options, such as a source address to bind (ip) or buffer sizes; only family was used. The options that apply to UDP now reach the HTTP/3 socket, and a shared HTTP/3 connection is reused only by requests with the same options. TCP-only options such as nodelay are ignored there, as before (#970).
  • WebTransport sessions ignored the socket options and family in connect_options. They now reach the socket: the UDP options over HTTP/3, the TCP options over HTTP/2 (#970).
  • A streamed request body (stream, then send_body and finish_send_body) ignored a Content-Length set by the caller. Over HTTP/1.1 hackney added Transfer-Encoding: chunked and chunk-framed the body anyway, so the request carried both headers and a server reading Content-Length saw the framing as body bytes: uploads of known size to stores that require it, such as S3, failed. Over HTTP/2 and HTTP/3 the header was sent but never checked, so a body of another size was reset by the server with an unclear error. The body now goes out as declared, and a body that does not match is an error: the HTTP/1.1 connection is closed, the HTTP/2 or HTTP/3 stream is reset and the connection stays usable. Over HTTP/1.1, when both headers are set, Content-Length is dropped.
  • Over HTTP/1.1, an empty write on a chunked request body ended the body early, and the next write went out as a stray request on the connection. It now sends nothing. A Transfer-Encoding such as gzip without chunked now gets chunked added, matching how hackney frames the body.
  • Closing an HTTP/2 connection over TLS could take about five seconds, and the other side learned it was gone only after that delay. hackney now uses h2 0.15.1, which closes without waiting for the peer, and webtransport 0.5.5, so a WebTransport session over HTTP/2 also learns at once that the peer closed.
Source: README.md, updated 2026-11-10