Releases: benoitc/hackney
Release list
4.7.4
Fixed
- A connection attempt that outlives its timeout no longer terminates the pool,
and with it every caller of that pool. The dial is made with the request's
connect_timeout, and a call that times out, like a connection process that
dies while dialing, comes back as a checkout error (#927, #928, thanks
@aboroska). - Handing a pooled connection to a new owner, and the prewarm dial, are guarded
like the other calls the pool makes into a connection process. A connection
that is gone or wedged is dropped instead of taking the pool down (#929). - Stopping a connection from inside the pool is bounded to 100ms, after which
the connection is killed. A connection wedged in a transport call, which a
failed dial makes likely, used to hold every caller of the pool for as long
as the transport took to return (#929). - The health probes the pool runs on a connection (
is_ready,checkin_info,
set_owner,get_state) take an explicit timeout, and the pool passes
250ms.h2_conn_usable/1used the 5s default, so one wedged HTTP/2
connection stalled the pool for 5 seconds on every checkout for that host
(#929).
Added
- Fault injection test harness for the pool: a transport which can be told to
misbehave, a sentinel which makes a dead pool visible, fault and chaos
suites, and a structural test which fails if the pool calls a connection
process outside atry.DEVELOPMENT.mdexplains how to use it (#929).
Changed
- Update dependencies to their latest releases:
h20.12.0 andwebtransport
0.4.5 (#930).
4.7.3
hackney 4.7.3 is a bugfix and hardening release for the Erlang HTTP client. It clears a few ways a pooled connection could stall or leak, hardens CRLF handling on the proxy and streaming request paths, restores curl-style Content-Length: 0 on empty POST/PUT/PATCH bodies (so servers such as AWS that require the header are happy again), and refreshes every dependency to its latest release.
Upgrading from 4.7.2 needs no code changes.
Fixed
- Reusing a pooled HTTP/2 or HTTP/3 connection no longer crashes the caller of
hackney:connect/4when the pooled connection terminates during the checkout
liveness probe. Theget_stateprobe is guarded so a terminating connection
falls through to a fresh one (#914). hackney_url:normalize/2now rejects a host that reaches an IP literal only
after IDNA folds the Unicode full-stop variants (U+3002/U+FF0E/U+FF61) to
ASCII dots (for example127。0。0。1becoming127.0.0.1), closing a bypass
of the percent-encoded-IP check.- The CONNECT proxy handshake rejects CR/LF/NUL in the target host instead of
concatenating it into the request line andHostheader. - The pooled HTTPS upgrade bounds the TLS handshake with
connect_timeout
(ssl:connect/3), so a server that stalls the handshake no longer pins the
connection process and its pool slot (#916). - The streaming request path sanitizes header values (CR/LF) like the buffered
path, and the request method is validated (CR/LF/NUL) at every entry point,
not just the request target. - A response body cut short by the peer closing mid-transfer no longer leaks
the connection process.read_full_body/2hands backsocket = undefined,
so the connection went straight toclosedand never reached the reuse
check added for #902. An unpooled connection arms no grace timer there and,
when started underhackney_conn_sup, has the supervisor as itsowner, so
the owner-DOWN clause never fired either: the process parked forever holding
every refc binary it had read. Callers could not clean up, since a
synchronous request returns the body directly and the truncated read still
reports{ok, Body}(#918). The same applies to a failed body read and to
bodyless (204/304) responses. hackney_conn:get_location/1andset_location/2no longer exit with
noprocwhen the connection has already stopped, which would otherwise
propagate out ofhackney:request/5on the redirect path.
Changed
- Like curl, an empty body on a body-bearing method (POST/PUT/PATCH) now sends
Content-Length: 0; bodyless methods (GET/HEAD/DELETE) are unchanged (#917). - Update dependencies to their latest releases:
quic1.8.0,webtransport
0.4.4,mimerl1.5.0, andcowboy2.18.0 for the test suite.
4.7.2
Bump quic to 1.7.1. A clean QUIC connection close (idle pooled HTTP/3 connections, orderly shutdown) no longer emits ERROR and CRASH reports from quic_h3_connection nor propagates an abnormal exit to the connection owner. This also removes the intermittent eunit group cancellation in the h3/wt test suites.
See NEWS.md for details. PR #913.
4.7.1
Chunked decoding no longer fails with {error, invalid_chunk_size} when the CRLF terminating a chunk-size line is split across two socket reads (buffer ending on a lone \r). The parser now waits for the \n (#901).
A malformed chunk-size line or chunk terminator now fails cleanly with {error, invalid_chunk_size} or {error, poorly_formatted_chunked_size} instead of crashing the parser with a case_clause error.
See NEWS.md for details. PR #912.
4.7.0
HTTP/2 request bodies larger than the peer's flow control window no longer fail with {error, send_buffer_full}. Body sends block until the server opens the window, bounded by the new send_timeout option (default 30000 ms, infinity allowed, nonblock restores the old fail-fast behavior). If the window never opens the request fails with {error, timeout} and the abandoned stream is reset so its buffered body does not linger on a shared connection. Applies to whole-body and streamed HTTP/2 request bodies; HTTP/1.1 and HTTP/3 are unchanged.
HTTP/2 async requests now deliver their response messages: the stream entry stored an internal reference where the delivery code expected the stream_to pid, so every async HTTP/2 response was silently dropped.
HTTP/2 {async, once} now honors stream_next/1 with the same contract as HTTP/1.1: status and headers eagerly, then one message per pull. once streams use h2 manual flow control, so a slow consumer keeps the peer's window closed and in-flight data stays bounded to one window.
Connections created with hackney:connect/4 and {pool, false} honor a {send_timeout, T} connect option; pooled connections keep the default and take the per-request option instead.
See NEWS.md for details. PR #911.
4.6.1
4.6.0
Added
set_owner/2now works while a response body is streaming, in both the synchronous and the async path. It used to return{error, invalid_state}once the body had started. This lets a short lived worker run a request and hand the still streaming response to a longer lived process before it exits, without stopping the connection.connect/4accepts a binary host, restoring the 1.x behavior. A binary is converted to a string, so callers passing a binary host no longer fail.
Fixed
- A non-reusable connection (flagged
no_reusefor proxy tunnels, SSL upgrades or a disabled pool, or answered withConnection: close) is now closed and its process stopped when a synchronous request completes, instead of parking inconnectedforever. With a long lived owner nothing stopped it, so onehackney_connprocess leaked per request until the node ran out of memory (#902). The sync and async reuse decision now share the same check, which also stops ano_reusepooled connection on the async path.
hackney 4.5.2
Dependency bump release. No API changes.
Changed
- Bump
h2to 0.10.4. It fixes a regression from 0.10.3 where a blocking send whose data had fully drained received{error, stream_closed}when the stream closed on its END_STREAM chunk. A waiting sender is now settled asokonce the send buffer has drained, and only gets the close-reason error when data is still outstanding. - Bump
quicto 1.7.0. Relevant to hackney's HTTP/3 client: the connection flow-control window now slides forward with received bytes instead of stalling after 8 MiB, so large HTTP/3 downloads keep flowing; the idle timer restarts on received activity per RFC 9000 §10.1; an invalid peer SETTINGS frame now closes the connection cleanly instead of crashing; and a client recognizes a server stateless reset (RFC 9000 §10.3) and closes promptly instead of waiting for the idle timeout. - Bump
webtransportto 0.4.3, which aligns its transitiveh2(0.10.4) andquic(1.7.0) dependencies with hackney's own, so thewt_*API runs on the same HTTP/2 and HTTP/3 stack versions.
4.5.1
Changed
- Bump
h2to 0.10.3. It fixes an HTTP/2 upload hang: a sender blocked on
flow control is now released with{error, stream_reset}or
{error, stream_closed}when the peer cancels the stream, instead of
hanging for the connection's lifetime. This affects hackney's streamed
request bodies over HTTP/2 when the server resets the stream
mid-backpressure.
4.5.0
Added
- HTTP QUERY method (RFC 10008) as a first-class method:
hackney:query/1..4
helpers andhackney:request(query, ...). QUERY is safe and idempotent and
carries a request body like POST. It works over HTTP/1.1, HTTP/2, and
HTTP/3 with every request body mode (binary, streamed, async, connection
API).