aboutsummaryrefslogtreecommitdiff
path: root/lib/pleroma/http/adapter_helper
diff options
context:
space:
mode:
authorAlexander Strizhakov <alex.strizhakov@gmail.com>2020-03-03 18:53:44 +0300
committerAlexander Strizhakov <alex.strizhakov@gmail.com>2020-03-03 18:53:44 +0300
commitf98ee730f01de528797e38f27964b69a465662c4 (patch)
treef15957c800066361ee9031f120edbd205f069cb5 /lib/pleroma/http/adapter_helper
parent8854770fc4e9079131a0897d5fb6c0ccccf98bc6 (diff)
downloadpleroma-f98ee730f01de528797e38f27964b69a465662c4.tar.gz
adapter renaming to adapter_helper
Diffstat (limited to 'lib/pleroma/http/adapter_helper')
-rw-r--r--lib/pleroma/http/adapter_helper/gun.ex120
-rw-r--r--lib/pleroma/http/adapter_helper/hackney.ex41
2 files changed, 161 insertions, 0 deletions
diff --git a/lib/pleroma/http/adapter_helper/gun.ex b/lib/pleroma/http/adapter_helper/gun.ex
new file mode 100644
index 000000000..b3298ec7f
--- /dev/null
+++ b/lib/pleroma/http/adapter_helper/gun.ex
@@ -0,0 +1,120 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.HTTP.AdapterHelper.Gun do
+ @behaviour Pleroma.HTTP.AdapterHelper
+
+ alias Pleroma.HTTP.AdapterHelper
+
+ require Logger
+
+ alias Pleroma.Pool.Connections
+
+ @defaults [
+ connect_timeout: 5_000,
+ domain_lookup_timeout: 5_000,
+ tls_handshake_timeout: 5_000,
+ retry: 1,
+ retry_timeout: 1000,
+ await_up_timeout: 5_000
+ ]
+
+ @spec options(keyword(), URI.t()) :: keyword()
+ def options(connection_opts \\ [], %URI{} = uri) do
+ proxy = Pleroma.Config.get([:http, :proxy_url], nil)
+
+ @defaults
+ |> Keyword.merge(Pleroma.Config.get([:http, :adapter], []))
+ |> add_original(uri)
+ |> add_scheme_opts(uri)
+ |> AdapterHelper.maybe_add_proxy(AdapterHelper.format_proxy(proxy))
+ |> maybe_get_conn(uri, connection_opts)
+ end
+
+ @spec after_request(keyword()) :: :ok
+ def after_request(opts) do
+ with conn when not is_nil(conn) <- opts[:conn],
+ body_as when body_as != :chunks <- opts[:body_as] do
+ Connections.checkout(conn, self(), :gun_connections)
+ end
+
+ :ok
+ end
+
+ defp add_original(opts, %URI{host: host, port: port}) do
+ formatted_host = format_host(host)
+
+ Keyword.put(opts, :original, "#{formatted_host}:#{port}")
+ end
+
+ defp add_scheme_opts(opts, %URI{scheme: "http"}), do: opts
+
+ defp add_scheme_opts(opts, %URI{scheme: "https", host: host, port: port}) do
+ adapter_opts = [
+ certificates_verification: true,
+ tls_opts: [
+ verify: :verify_peer,
+ cacertfile: CAStore.file_path(),
+ depth: 20,
+ reuse_sessions: false,
+ verify_fun: {&:ssl_verify_hostname.verify_fun/3, [check_hostname: format_host(host)]},
+ log_level: :warning
+ ]
+ ]
+
+ adapter_opts =
+ if port != 443 do
+ Keyword.put(adapter_opts, :transport, :tls)
+ else
+ adapter_opts
+ end
+
+ Keyword.merge(opts, adapter_opts)
+ end
+
+ defp maybe_get_conn(adapter_opts, uri, connection_opts) do
+ {receive_conn?, opts} =
+ adapter_opts
+ |> Keyword.merge(connection_opts)
+ |> Keyword.pop(:receive_conn, true)
+
+ if Connections.alive?(:gun_connections) and receive_conn? do
+ try_to_get_conn(uri, opts)
+ else
+ opts
+ end
+ end
+
+ defp try_to_get_conn(uri, opts) do
+ case Connections.checkin(uri, :gun_connections) do
+ nil ->
+ Logger.debug(
+ "Gun connections pool checkin was not successful. Trying to open conn for next request."
+ )
+
+ Task.start(fn -> Pleroma.Gun.Conn.open(uri, :gun_connections, opts) end)
+ opts
+
+ conn when is_pid(conn) ->
+ Logger.debug("received conn #{inspect(conn)} #{Connections.compose_uri_log(uri)}")
+
+ opts
+ |> Keyword.put(:conn, conn)
+ |> Keyword.put(:close_conn, false)
+ end
+ end
+
+ @spec format_host(String.t()) :: charlist()
+ def format_host(host) do
+ host_charlist = to_charlist(host)
+
+ case :inet.parse_address(host_charlist) do
+ {:error, :einval} ->
+ :idna.encode(host_charlist)
+
+ {:ok, _ip} ->
+ host_charlist
+ end
+ end
+end
diff --git a/lib/pleroma/http/adapter_helper/hackney.ex b/lib/pleroma/http/adapter_helper/hackney.ex
new file mode 100644
index 000000000..a0e161eaa
--- /dev/null
+++ b/lib/pleroma/http/adapter_helper/hackney.ex
@@ -0,0 +1,41 @@
+defmodule Pleroma.HTTP.AdapterHelper.Hackney do
+ @behaviour Pleroma.HTTP.AdapterHelper
+
+ @defaults [
+ connect_timeout: 10_000,
+ recv_timeout: 20_000,
+ follow_redirect: true,
+ force_redirect: true,
+ pool: :federation
+ ]
+
+ @spec options(keyword(), URI.t()) :: keyword()
+ def options(connection_opts \\ [], %URI{} = uri) do
+ proxy = Pleroma.Config.get([:http, :proxy_url], nil)
+
+ @defaults
+ |> Keyword.merge(Pleroma.Config.get([:http, :adapter], []))
+ |> Keyword.merge(connection_opts)
+ |> add_scheme_opts(uri)
+ |> Pleroma.HTTP.AdapterHelper.maybe_add_proxy(proxy)
+ end
+
+ defp add_scheme_opts(opts, %URI{scheme: "http"}), do: opts
+
+ defp add_scheme_opts(opts, %URI{scheme: "https", host: host}) do
+ ssl_opts = [
+ ssl_options: [
+ # Workaround for remote server certificate chain issues
+ partial_chain: &:hackney_connect.partial_chain/1,
+
+ # We don't support TLS v1.3 yet
+ versions: [:tlsv1, :"tlsv1.1", :"tlsv1.2"],
+ server_name_indication: to_charlist(host)
+ ]
+ ]
+
+ Keyword.merge(opts, ssl_opts)
+ end
+
+ def after_request(_), do: :ok
+end