fix(deps): pin Hackney to the connection-leak fix

An unpooled Hackney 4 connection that ends without a reusable socket -- a
body cut short by the peer, a bodyless 204/304, or a failed read -- parks
in its `closed` state forever, holding every refc binary it read.
read_full_body/2 hands back `socket = undefined`, so it never reaches the
reuse check; `closed(enter)` arms a stop timer only for pooled
connections; and an unpooled connection is owned by hackney_conn_sup, so
the owner-DOWN cleanup never fires.

Nothing here can work around it. Since 4.0 Hackney ignores `with_body`
and always returns a fully read binary, so a synchronous request never
yields a handle to close, and the short read still reports {:ok, body}.
Media proxy warming hits this whenever an attachment fetch is cut short
and the outbound proxy is used as a CONNECT tunnel, since tunnels are
never pooled.

Pin the fix, a single commit on top of the 4.7.2 tag, until it ships in a
release. While it is a git dep Hackney drops out of `mix deps.audit` and
`mix hex.outdated`, so this wants moving back to hex promptly.

benoitc/hackney#918, benoitc/hackney#919
This commit is contained in:
Lain Soykaf 2026-07-26 10:15:52 +04:00
commit 42c100605e
No known key found for this signature in database
3 changed files with 19 additions and 2 deletions

View file

@ -0,0 +1 @@
Stop leaking a Hackney connection process, and the response bytes it read, for every unpooled request that ends without a reusable socket

18
mix.exs
View file

@ -218,7 +218,23 @@ defmodule Pleroma.Mixfile do
{:covertool, "~> 2.0", only: :test},
# Hackney 4.7 requires h2 0.11 while WebTransport still declares 0.10.x.
{:h2, "~> 0.11.0", override: true},
{:hackney, "~> 4.7.2", override: true},
# 4.7.2 plus https://github.com/benoitc/hackney/pull/919, which is a single
# commit on top of the 4.7.2 tag (`git diff 4.7.2..5042f6a` to review it).
# An unpooled connection that ends without a reusable socket -- a body cut
# short by the peer, a bodyless 204/304, or a failed read -- parks forever
# holding what it read, and nothing downstream can release it. Media proxy
# warming hits that whenever an attachment fetch is cut short and the
# outbound proxy is used as a CONNECT tunnel, since tunnels are never
# pooled. See test/pleroma/http/hackney_conn_leak_test.exs and
# https://github.com/benoitc/hackney/issues/918.
#
# Being a git dep, hackney is invisible to `mix deps.audit` and
# `mix hex.outdated` until this moves back to a hex release, which should
# happen as soon as the fix ships in one.
{:hackney,
git: "https://github.com/lambadalambda/hackney.git",
ref: "5042f6a09df526a46de2c8945634f95605d2fc76",
override: true},
{:mox, "~> 1.2", only: :test},
{:websockex, "~> 0.4.3", only: :test},
{:benchee, "~> 1.4", only: :benchmark},

View file

@ -59,7 +59,7 @@
"gettext": {:hex, :gettext, "0.24.0", "6f4d90ac5f3111673cbefc4ebee96fe5f37a114861ab8c7b7d5b30a1108ce6d8", [:mix], [{:expo, "~> 0.5.1", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "bdf75cdfcbe9e4622dd18e034b227d77dd17f0f133853a1c73b97b3d6c770e8b"},
"gun": {:hex, :gun, "2.4.1", "c3a8bff8e155e1fc8e499216599bb7effbd27bc1985662a8b25016090dc18428", [:make, :rebar3], [{:cowlib, ">= 2.15.0 and < 3.0.0", [hex: :cowlib, repo: "hexpm", optional: false]}], "hexpm", "1450575b4d393aa0811322727b90ad1dd94b5c10026f54a1641785bcbd250384"},
"h2": {:hex, :h2, "0.11.0", "b8c9f7c86f400582c5cbed59f79c0efd6cf49ad6478c210bede91d2d15019b14", [:rebar3], [], "hexpm", "c61f24361d0dc76375eaf35c2bf0e01235d81b7685538df571db036467fac358"},
"hackney": {:hex, :hackney, "4.7.2", "8f712c94d90220cc21ea8049172c2e760ffc41737060667603aa1aef52ab9a4d", [:rebar3], [{:certifi, "~> 2.17.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:h2, "~> 0.11.0", [hex: :h2, repo: "hexpm", optional: false]}, {:idna, "~> 7.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.4", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.2", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:webtransport, "~> 0.4.3", [hex: :webtransport, repo: "hexpm", optional: false]}], "hexpm", "fad03e527a6b1811ef3362ebe9d6d826d988927c18afc71358c35bf2098110e4"},
"hackney": {:git, "https://github.com/lambadalambda/hackney.git", "5042f6a09df526a46de2c8945634f95605d2fc76", [ref: "5042f6a09df526a46de2c8945634f95605d2fc76"]},
"hpax": {:hex, :hpax, "1.0.4", "777de5d433b0fbdc7c418159c8055910faa8047ffdb3d6b31098d2a46cd7685c", [:mix], [], "hexpm", "afc7cb142ebcc2d01ce7816190b98ce5dd49e799111b24249f3443d730f377ca"},
"html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"},
"http_signatures": {:hex, :http_signatures, "0.1.3", "19f26aee35b4684e37efdce3ac4638605e6e41a04368186bd39d2b6138a60ea9", [:mix], [{:plug, "~> 1.18", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "20313a65516db88006f85b090f6f76cc5b04e9609b45943657e6781eb91174f4"},