From 4943e6a9147d62a326d94cc88edaf513f6f8f342 Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Thu, 22 Oct 2026 16:23:40 +0400 Subject: [PATCH] fix(http): pass IP proxy hosts to Hackney as strings ConfigDB turns a numeric proxy host into an IP tuple. Hackney 1 took it, Hackney 4 ignores such a proxy and connects directly, which skips a SOCKS proxy (Tor) without any error. --- changelog.d/hackney-proxy-ip-host.fix | 1 + lib/pleroma/http/adapter_helper/hackney.ex | 16 ++++++++++++++++ .../pleroma/http/adapter_helper/hackney_test.exs | 13 +++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 changelog.d/hackney-proxy-ip-host.fix diff --git a/changelog.d/hackney-proxy-ip-host.fix b/changelog.d/hackney-proxy-ip-host.fix new file mode 100644 index 000000000..5d11aadd5 --- /dev/null +++ b/changelog.d/hackney-proxy-ip-host.fix @@ -0,0 +1 @@ +Hackney: use the configured proxy when its host is an IP address; Hackney 4 ignored such proxies and connected directly \ No newline at end of file diff --git a/lib/pleroma/http/adapter_helper/hackney.ex b/lib/pleroma/http/adapter_helper/hackney.ex index 314f9e8b1..e9cc04361 100644 --- a/lib/pleroma/http/adapter_helper/hackney.ex +++ b/lib/pleroma/http/adapter_helper/hackney.ex @@ -30,6 +30,22 @@ defmodule Pleroma.HTTP.AdapterHelper.Hackney do |> Pleroma.HTTP.AdapterHelper.maybe_add_proxy(proxy) |> Keyword.put(:follow_redirect, false) |> Keyword.put(:force_redirect, false) + |> normalize_proxy() + end + + # Hackney 4 ignores a proxy whose host is an IP tuple and connects directly. + # ConfigDB turns a numeric proxy host into such a tuple. + defp normalize_proxy(opts) do + case Keyword.fetch(opts, :proxy) do + {:ok, {type, host, port}} when is_tuple(host) -> + Keyword.put(opts, :proxy, {type, :inet.ntoa(host), port}) + + {:ok, {host, port}} when is_tuple(host) -> + Keyword.put(opts, :proxy, {:inet.ntoa(host), port}) + + _ -> + opts + end end defp add_scheme_opts(opts, _), do: opts diff --git a/test/pleroma/http/adapter_helper/hackney_test.exs b/test/pleroma/http/adapter_helper/hackney_test.exs index cf60d994b..22fcc93d1 100644 --- a/test/pleroma/http/adapter_helper/hackney_test.exs +++ b/test/pleroma/http/adapter_helper/hackney_test.exs @@ -39,6 +39,19 @@ defmodule Pleroma.HTTP.AdapterHelper.HackneyTest do assert opts[:proxy] == "localhost:8123" end + test "gives Hackney a string host for a proxy with an IP address", %{uri: uri} do + clear_config([:http, :proxy_url], {:socks5, {127, 0, 0, 1}, 9050}) + assert Hackney.options([], uri)[:proxy] == {:socks5, ~c"127.0.0.1", 9050} + + clear_config([:http, :proxy_url], {{10, 0, 0, 1}, 8123}) + assert Hackney.options([], uri)[:proxy] == {~c"10.0.0.1", 8123} + + clear_config([:http, :proxy_url], nil) + + assert Hackney.options([proxy: {:socks5, {0, 0, 0, 0, 0, 0, 0, 1}, 9050}], uri)[:proxy] == + {:socks5, ~c"::1", 9050} + end + test "respect connection opts and no proxy", %{uri: uri} do opts = Hackney.options([a: 2, b: 1], uri)