Page MenuHomePhorge

No OneTemporary

Size
2 KB
Referenced Files
None
Subscribers
None
diff --git a/changelog.d/hackney-mediaproxy.change b/changelog.d/hackney-mediaproxy.change
new file mode 100644
index 000000000..10dfb0775
--- /dev/null
+++ b/changelog.d/hackney-mediaproxy.change
@@ -0,0 +1 @@
+Use a custom redirect handler to ensure MediaProxy redirects are followed with Hackney
diff --git a/lib/pleroma/reverse_proxy/client/hackney.ex b/lib/pleroma/reverse_proxy/client/hackney.ex
index 0aa5f5715..7ccd28bb1 100644
--- a/lib/pleroma/reverse_proxy/client/hackney.ex
+++ b/lib/pleroma/reverse_proxy/client/hackney.ex
@@ -1,29 +1,71 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.ReverseProxy.Client.Hackney do
@behaviour Pleroma.ReverseProxy.Client
+ # redirect handler from Pleb, slightly modified to work with Hackney
+ # https://declin.eu/objects/d4f38e62-5429-4614-86d1-e8fc16e6bf33
+ # https://github.com/benoitc/hackney/issues/273
+ @redirect_statuses [301, 302, 303, 307, 308]
+ defp absolute_redirect_url(original_url, resp_headers) do
+ location =
+ Enum.find(resp_headers, fn {header, _location} ->
+ String.downcase(header) == "location"
+ end)
+
+ URI.merge(original_url, elem(location, 1))
+ |> URI.to_string()
+ end
+
@impl true
def request(method, url, headers, body, opts \\ []) do
opts =
Keyword.put_new(opts, :path_encode_fun, fn path ->
path
end)
- :hackney.request(method, url, headers, body, opts)
+ if opts[:follow_redirect] != false do
+ {_state, req_opts} = Access.get_and_update(opts, :follow_redirect, fn a -> {a, false} end)
+ res = :hackney.request(method, url, headers, body, req_opts)
+
+ case res do
+ {:ok, code, resp_headers, _client} when code in @redirect_statuses ->
+ :hackney.request(
+ method,
+ absolute_redirect_url(url, resp_headers),
+ headers,
+ body,
+ req_opts
+ )
+
+ {:ok, code, resp_headers} when code in @redirect_statuses ->
+ :hackney.request(
+ method,
+ absolute_redirect_url(url, resp_headers),
+ headers,
+ body,
+ req_opts
+ )
+
+ _ ->
+ res
+ end
+ else
+ :hackney.request(method, url, headers, body, opts)
+ end
end
@impl true
def stream_body(ref) do
case :hackney.stream_body(ref) do
:done -> :done
{:ok, data} -> {:ok, data, ref}
{:error, error} -> {:error, error}
end
end
@impl true
def close(ref), do: :hackney.close(ref)
end

File Metadata

Mime Type
text/x-diff
Expires
Sun, Aug 30, 2:21 PM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1738029
Default Alt Text
(2 KB)

Event Timeline