aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlex S <alex.strizhakov@gmail.com>2019-08-08 18:42:50 +0300
committerAlex S <alex.strizhakov@gmail.com>2019-08-20 12:39:53 +0300
commit4e9d9209c3c598532e1eaacb35e276357906afb4 (patch)
tree2aaa94ca4f84bb874d3e0eb974dd791f18a5d557 /lib
parentb383d85b9b8229751dd538c66e02a18f2de45835 (diff)
downloadpleroma-4e9d9209c3c598532e1eaacb35e276357906afb4.tar.gz
added tesla client for reverse proxy
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/http/connection.ex6
-rw-r--r--lib/pleroma/reverse_proxy/client.ex17
-rw-r--r--lib/pleroma/reverse_proxy/client/hackney.ex17
-rw-r--r--lib/pleroma/reverse_proxy/client/tesla.ex48
-rw-r--r--lib/pleroma/reverse_proxy/reverse_proxy.ex10
5 files changed, 82 insertions, 16 deletions
diff --git a/lib/pleroma/http/connection.ex b/lib/pleroma/http/connection.ex
index 8caf989a7..4ebe16e18 100644
--- a/lib/pleroma/http/connection.ex
+++ b/lib/pleroma/http/connection.ex
@@ -10,11 +10,7 @@ defmodule Pleroma.HTTP.Connection do
@options [
connect_timeout: 10_000,
protocols: [:http],
- timeout: 20_000,
- recv_timeout: 20_000,
- follow_redirect: true,
- force_redirect: true,
- pool: :federation
+ timeout: 20_000
]
@adapter Application.get_env(:tesla, :adapter)
diff --git a/lib/pleroma/reverse_proxy/client.ex b/lib/pleroma/reverse_proxy/client.ex
index 776c4794c..42f2ff13b 100644
--- a/lib/pleroma/reverse_proxy/client.ex
+++ b/lib/pleroma/reverse_proxy/client.ex
@@ -3,9 +3,14 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.ReverseProxy.Client do
- @callback request(atom(), String.t(), [tuple()], String.t(), list()) ::
- {:ok, pos_integer(), [tuple()], reference() | map()}
- | {:ok, pos_integer(), [tuple()]}
+ @type status :: pos_integer()
+ @type header_name :: String.t()
+ @type header_value :: String.t()
+ @type headers :: [{header_name(), header_value()}]
+
+ @callback request(atom(), String.t(), headers(), String.t(), list()) ::
+ {:ok, status(), headers(), reference() | map()}
+ | {:ok, status(), headers()}
| {:ok, reference()}
| {:error, term()}
@@ -14,8 +19,8 @@ defmodule Pleroma.ReverseProxy.Client do
@callback close(reference() | pid() | map()) :: :ok
- def request(method, url, headers, "", opts \\ []) do
- client().request(method, url, headers, "", opts)
+ def request(method, url, headers, body \\ "", opts \\ []) do
+ client().request(method, url, headers, body, opts)
end
def stream_body(ref), do: client().stream_body(ref)
@@ -23,6 +28,6 @@ defmodule Pleroma.ReverseProxy.Client do
def close(ref), do: client().close(ref)
defp client do
- Pleroma.Config.get([Pleroma.ReverseProxy.Client], :hackney)
+ Pleroma.Config.get([Pleroma.ReverseProxy.Client], Pleroma.ReverseProxy.Client.Hackney)
end
end
diff --git a/lib/pleroma/reverse_proxy/client/hackney.ex b/lib/pleroma/reverse_proxy/client/hackney.ex
new file mode 100644
index 000000000..e6293646a
--- /dev/null
+++ b/lib/pleroma/reverse_proxy/client/hackney.ex
@@ -0,0 +1,17 @@
+defmodule Pleroma.ReverseProxy.Client.Hackney do
+ @behaviour Pleroma.ReverseProxy.Client
+
+ def request(method, url, headers, body, opts \\ []) do
+ :hackney.request(method, url, headers, body, opts)
+ end
+
+ def stream_body(ref) do
+ case :hackney.stream_body(ref) do
+ :done -> :done
+ {:ok, data} -> {:ok, data, ref}
+ {:error, error} -> {:error, error}
+ end
+ end
+
+ def close(ref), do: :hackney.close(ref)
+end
diff --git a/lib/pleroma/reverse_proxy/client/tesla.ex b/lib/pleroma/reverse_proxy/client/tesla.ex
new file mode 100644
index 000000000..d2944b9dc
--- /dev/null
+++ b/lib/pleroma/reverse_proxy/client/tesla.ex
@@ -0,0 +1,48 @@
+defmodule Pleroma.ReverseProxy.Client.Tesla do
+ @behaviour Pleroma.ReverseProxy.Client
+
+ @adapters [Tesla.Adapter.Gun]
+ alias Pleroma.HTTP
+
+ def request(method, url, headers, body, opts \\ []) do
+ adapter_opts =
+ Keyword.get(opts, :adapter, [])
+ |> Keyword.put(:chunks_response, true)
+
+ with {:ok, response} <-
+ HTTP.request(method, url, body, headers, Keyword.put(opts, :adapter, adapter_opts)) do
+ {:ok, response.status, response.headers, response.body}
+ else
+ {:error, error} -> {:error, error}
+ end
+ end
+
+ def stream_body(%{fin: true}), do: :done
+
+ def stream_body(client) do
+ case read_chunk!(client) do
+ {:fin, body} -> {:ok, body, Map.put(client, :fin, true)}
+ {:nofin, part} -> {:ok, part, client}
+ end
+ end
+
+ defp read_chunk!(client) do
+ adapter = Application.get_env(:tesla, :adapter)
+
+ unless adapter in @adapters do
+ raise "#{adapter} doesn't support reading body in chunks"
+ end
+
+ adapter.read_chunk(client)
+ end
+
+ def close(client) do
+ adapter = Application.get_env(:tesla, :adapter)
+
+ unless adapter in @adapters do
+ raise "#{adapter} doesn't support closing connection"
+ end
+
+ adapter.close(client)
+ end
+end
diff --git a/lib/pleroma/reverse_proxy/reverse_proxy.ex b/lib/pleroma/reverse_proxy/reverse_proxy.ex
index 3212bf90d..a2cdcf393 100644
--- a/lib/pleroma/reverse_proxy/reverse_proxy.ex
+++ b/lib/pleroma/reverse_proxy/reverse_proxy.ex
@@ -61,7 +61,7 @@ defmodule Pleroma.ReverseProxy do
* `http`: options for [hackney](https://github.com/benoitc/hackney).
"""
- @default_hackney_options [pool: :media]
+ @default_options [pool: :media]
@inline_content_types [
"image/gif",
@@ -93,9 +93,9 @@ defmodule Pleroma.ReverseProxy do
def call(_conn, _url, _opts \\ [])
def call(conn = %{method: method}, url, opts) when method in @methods do
- hackney_opts =
+ client_opts =
Pleroma.HTTP.Connection.options([])
- |> Keyword.merge(@default_hackney_options)
+ |> Keyword.merge(@default_options)
|> Keyword.merge(Keyword.get(opts, :http, []))
|> HTTP.process_request_options()
@@ -108,7 +108,7 @@ defmodule Pleroma.ReverseProxy do
opts
end
- with {:ok, code, headers, client} <- request(method, url, req_headers, hackney_opts),
+ with {:ok, code, headers, client} <- request(method, url, req_headers, client_opts),
:ok <-
header_length_constraint(
headers,
@@ -201,7 +201,7 @@ defmodule Pleroma.ReverseProxy do
duration,
Keyword.get(opts, :max_read_duration, @max_read_duration)
),
- {:ok, data} <- client().stream_body(client),
+ {:ok, data, client} <- client().stream_body(client),
{:ok, duration} <- increase_read_duration(duration),
sent_so_far = sent_so_far + byte_size(data),
:ok <-