Track failed proxy urls and don't request them again
This commit is contained in:
parent
51b5c53988
commit
c541b83bef
4 changed files with 80 additions and 9 deletions
|
|
@ -102,7 +102,8 @@ defmodule Pleroma.Application do
|
|||
build_cachex("scrubber", limit: 2500),
|
||||
build_cachex("idempotency", expiration: idempotency_expiration(), limit: 2500),
|
||||
build_cachex("web_resp", limit: 2500),
|
||||
build_cachex("emoji_packs", expiration: emoji_packs_expiration(), limit: 10)
|
||||
build_cachex("emoji_packs", expiration: emoji_packs_expiration(), limit: 10),
|
||||
build_cachex("failed_proxy_url", limit: 2500)
|
||||
]
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ defmodule Pleroma.ReverseProxy do
|
|||
@valid_resp_codes [200, 206, 304]
|
||||
@max_read_duration :timer.seconds(30)
|
||||
@max_body_length :infinity
|
||||
@failed_request_ttl :timer.seconds(60)
|
||||
@methods ~w(GET HEAD)
|
||||
|
||||
@moduledoc """
|
||||
|
|
@ -48,6 +49,8 @@ defmodule Pleroma.ReverseProxy do
|
|||
* `max_read_duration` (default `#{inspect(@max_read_duration)}` ms): the total time the connection is allowed to
|
||||
read from the remote upstream.
|
||||
|
||||
* `failed_request_ttl` (default `#{inspect(@failed_request_ttl)}` ms): the time the failed request is cached and cannot be retried.
|
||||
|
||||
* `inline_content_types`:
|
||||
* `true` will not alter `content-disposition` (up to the upstream),
|
||||
* `false` will add `content-disposition: attachment` to any request,
|
||||
|
|
@ -83,6 +86,7 @@ defmodule Pleroma.ReverseProxy do
|
|||
{:keep_user_agent, boolean}
|
||||
| {:max_read_duration, :timer.time() | :infinity}
|
||||
| {:max_body_length, non_neg_integer() | :infinity}
|
||||
| {:failed_request_ttl, :timer.time() | :infinity}
|
||||
| {:http, []}
|
||||
| {:req_headers, [{String.t(), String.t()}]}
|
||||
| {:resp_headers, [{String.t(), String.t()}]}
|
||||
|
|
@ -108,7 +112,8 @@ defmodule Pleroma.ReverseProxy do
|
|||
opts
|
||||
end
|
||||
|
||||
with {:ok, code, headers, client} <- request(method, url, req_headers, hackney_opts),
|
||||
with {:ok, nil} <- Cachex.get(:failed_proxy_url_cache, url),
|
||||
{:ok, code, headers, client} <- request(method, url, req_headers, hackney_opts),
|
||||
:ok <-
|
||||
header_length_constraint(
|
||||
headers,
|
||||
|
|
@ -116,12 +121,18 @@ defmodule Pleroma.ReverseProxy do
|
|||
) do
|
||||
response(conn, client, url, code, headers, opts)
|
||||
else
|
||||
{:ok, true} ->
|
||||
conn
|
||||
|> error_or_redirect(url, 500, "Request failed", opts)
|
||||
|> halt()
|
||||
|
||||
{:ok, code, headers} ->
|
||||
head_response(conn, url, code, headers, opts)
|
||||
|> halt()
|
||||
|
||||
{:error, {:invalid_http_response, code}} ->
|
||||
Logger.error("#{__MODULE__}: request to #{inspect(url)} failed with HTTP status #{code}")
|
||||
track_failed_url(url, code, opts)
|
||||
|
||||
conn
|
||||
|> error_or_redirect(
|
||||
|
|
@ -134,6 +145,7 @@ defmodule Pleroma.ReverseProxy do
|
|||
|
||||
{:error, error} ->
|
||||
Logger.error("#{__MODULE__}: request to #{inspect(url)} failed: #{inspect(error)}")
|
||||
track_failed_url(url, error, opts)
|
||||
|
||||
conn
|
||||
|> error_or_redirect(url, 500, "Request failed", opts)
|
||||
|
|
@ -388,4 +400,17 @@ defmodule Pleroma.ReverseProxy do
|
|||
end
|
||||
|
||||
defp client, do: Pleroma.ReverseProxy.Client
|
||||
|
||||
defp track_failed_url(url, code, opts) do
|
||||
code = to_string(code)
|
||||
|
||||
ttl =
|
||||
if code in ["403", "404"] or String.starts_with?(code, "5") do
|
||||
Keyword.get(opts, :failed_request_ttl, @failed_request_ttl)
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
||||
Cachex.put(:failed_proxy_url_cache, url, true, ttl: ttl)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue