Skip to content

4.9.0

Choose a tag to compare

@benoitc benoitc released this 25 Oct 21:39
· 3 commits to master since this release
0f5db33

Added

  • A max_body_size request option caps a response body that hackney
    buffers for you (the default hackney:request result, or body/1).
    It defaults to 512 MiB and also accepts the 1.x name max_body;
    infinity turns it off (#980).

Fixed

  • URLs that hide a loopback or private IP inside a percent-encoded
    bracketed IPv6 address, or behind a trailing dot, are now refused like
    other IP literals. The earlier fix for CVE-2026-47076 missed these two
    spellings, so such a URL still reached the address it denotes (#987).
  • Pinning your own CA with cacerts or cacertfile now actually limits
    which servers are trusted. hackney still accepted any certificate chain
    that included a publicly trusted root, so a pinned connection could reach
    a server its CA never vouched for (#978).
  • Following a redirect no longer resends basic_auth and cookie to
    another port on the same host, or over plain HTTP after HTTPS. Only a
    redirect to the same scheme, host and port keeps them, unless you set
    location_trusted (#979).
  • A server sending an endless or highly compressed body can no longer
    exhaust memory. Buffered bodies had no limit on HTTP/1.1, HTTP/2 and
    HTTP/3, and auto_decompress inflated the whole body at once. Both now
    stop at max_body_size with {error, body_too_large} (#980).
  • HTTPS proxies reached through CONNECT now get the same certificate checks
    as the target: hackney's CA bundle and a hostname check against the
    proxy. The connection to the proxy only set the server name, so on
    OTP 27 and later it failed unless proxy_ssl_options set cacerts or
    verify_none. An explicit {verify, verify_none} is still honoured (#988).
  • A proxy_auth_fun that returns a value containing CR, LF or NUL is now
    refused with {error, {proxy_auth_error, invalid_header}}. The value was
    written as is into the CONNECT request, so those bytes added header lines
    of their own (#989).
  • A slow or unreachable host no longer stalls every request that goes
    through the same pool. The pool opened new connections itself, so while
    one host took its time to answer, checkouts for every other host waited,
    for up to connect_timeout. The requester now opens its own connection,
    as in hackney 1.x (#973).
  • A failed TLS handshake on a pooled connection no longer frees a
    max_per_host slot held by another request. The slot was released twice,
    so the host could get one more concurrent connection than allowed (#984).

Changed

  • Buffered downloads over 512 MiB now fail with {error, body_too_large}
    unless you raise max_body_size (#980).
  • If you pin cacerts that include the bundled public roots, hackney no
    longer falls back to trusting a cross-signed root it finds in the
    server's chain. Add the root you need to your list, or pass your own
    partial_chain (#978).