diff --git a/lib/pleroma/gun/api/mock.ex b/lib/pleroma/gun/api/mock.ex index 3348715c4..ff9e13a74 100644 --- a/lib/pleroma/gun/api/mock.ex +++ b/lib/pleroma/gun/api/mock.ex @@ -13,7 +13,7 @@ defmodule Pleroma.Gun.API.Mock do def open('some-domain.com', 443, %{genserver_pid: genserver_pid}) do {:ok, conn_pid} = Task.start_link(fn -> Process.sleep(1_000) end) - send(genserver_pid, {:gun_up, conn_pid, :https}) + send(genserver_pid, {:gun_up, conn_pid, :http2}) {:ok, conn_pid} end diff --git a/lib/pleroma/gun/connections.ex b/lib/pleroma/gun/connections.ex index 82579604a..6fcf4332a 100644 --- a/lib/pleroma/gun/connections.ex +++ b/lib/pleroma/gun/connections.ex @@ -100,8 +100,8 @@ defmodule Pleroma.Gun.Connections do def handle_call({:state}, _from, state), do: {:reply, state, state} @impl true - def handle_info({:gun_up, conn_pid, protocol}, state) do - {key, conn} = find_conn(state.conns, conn_pid, protocol) + def handle_info({:gun_up, conn_pid, _protocol}, state) do + {key, conn} = find_conn(state.conns, conn_pid) # Send to all waiting processes connection pid Enum.each(conn.waiting_pids, fn waiting_pid -> GenServer.reply(waiting_pid, conn_pid) end) @@ -113,8 +113,8 @@ defmodule Pleroma.Gun.Connections do @impl true # Do we need to do something with killed & unprocessed references? - def handle_info({:gun_down, conn_pid, protocol, _reason, _killed, _unprocessed}, state) do - {key, conn} = find_conn(state.conns, conn_pid, protocol) + def handle_info({:gun_down, conn_pid, _protocol, _reason, _killed, _unprocessed}, state) do + {key, conn} = find_conn(state.conns, conn_pid) # We don't want to block requests to GenServer if gun send down message, return nil, so we can make some retries, while connection is not up Enum.each(conn.waiting_pids, fn waiting_pid -> GenServer.reply(waiting_pid, nil) end) @@ -125,6 +125,10 @@ defmodule Pleroma.Gun.Connections do defp compose_key(uri), do: uri.host <> ":" <> to_string(uri.port) - defp find_conn(conns, conn_pid, protocol), - do: Enum.find(conns, fn {_, conn} -> conn.conn == conn_pid and conn.protocol == protocol end) + defp find_conn(conns, conn_pid) do + Enum.find(conns, fn {key, conn} -> + protocol = if String.ends_with?(key, ":443"), do: :https, else: :http + conn.conn == conn_pid and conn.protocol == protocol + end) + end end diff --git a/test/gun/connections_test.exs b/test/gun/connections_test.exs index 42354d330..aad70a644 100644 --- a/test/gun/connections_test.exs +++ b/test/gun/connections_test.exs @@ -201,5 +201,29 @@ defmodule Gun.ConnectionsTest do } } = Connections.get_state(name) end + + test "opens ssl connection and reuse it on next request", %{name: name} do + api = Pleroma.Config.get([API]) + Pleroma.Config.put([API], :gun) + on_exit(fn -> Pleroma.Config.put([API], api) end) + conn = Connections.get_conn("https://httpbin.org", [], name) + + assert is_pid(conn) + assert Process.alive?(conn) + + reused_conn = Connections.get_conn("https://httpbin.org", [], name) + + assert conn == reused_conn + + %Connections{ + conns: %{ + "httpbin.org:443" => %Conn{ + conn: ^conn, + state: :up, + waiting_pids: [] + } + } + } = Connections.get_state(name) + end end end diff --git a/test/reverse_proxy/reverse_proxy_test.exs b/test/reverse_proxy/reverse_proxy_test.exs index 2092b0dc3..c5563f955 100644 --- a/test/reverse_proxy/reverse_proxy_test.exs +++ b/test/reverse_proxy/reverse_proxy_test.exs @@ -370,5 +370,28 @@ defmodule Pleroma.ReverseProxyTest do Pleroma.Config.put([Pleroma.Gun.API], api) end) end + + test "with tesla client with gun adapter with ssl", %{conn: conn} do + client = Pleroma.Config.get([Pleroma.ReverseProxy.Client]) + Pleroma.Config.put([Pleroma.ReverseProxy.Client], Pleroma.ReverseProxy.Client.Tesla) + adapter = Application.get_env(:tesla, :adapter) + Application.put_env(:tesla, :adapter, Tesla.Adapter.Gun) + + api = Pleroma.Config.get([Pleroma.Gun.API]) + Pleroma.Config.put([Pleroma.Gun.API], :gun) + {:ok, _} = Pleroma.Gun.Connections.start_link(Pleroma.Gun.Connections) + + conn = ReverseProxy.call(conn, "https://httpbin.org/stream-bytes/10") + + assert byte_size(conn.resp_body) == 10 + assert conn.state == :chunked + assert conn.status == 200 + + on_exit(fn -> + Pleroma.Config.put([Pleroma.ReverseProxy.Client], client) + Application.put_env(:tesla, :adapter, adapter) + Pleroma.Config.put([Pleroma.Gun.API], api) + end) + end end end