puppyoma/lib/pleroma/web/puppy_media_proxy/puppy_proxy_controller.ex
2025-02-07 20:13:57 +01:00

53 lines
1.4 KiB
Elixir

defmodule Pleroma.Web.PuppyMediaProxy.PuppyProxyController do
use Pleroma.Web, :controller
require Logger
@max_body_length 1024 * 1024 * 1024
@valid_mime_types ["image/", "video/", "audio/"]
def get(conn, %{"url" => url}) do
with {:ok, %Tesla.Env{status: status, body: body, headers: headers}} <- fetch_media(url),
{:ok, content_type} <- get_content_type(headers),
:ok <- validate_mime_type(content_type) do
conn
|> put_resp_content_type(content_type)
|> put_resp_header("cache-control", "public, max-age=1209600")
|> send_resp(status, body)
else
{:error, :invalid_mime_type} ->
conn
|> put_status(:forbidden)
|> json(%{error: "Invalid media type"})
error ->
Logger.error("Media proxy error: #{inspect(error)}")
conn
|> put_status(:bad_request)
|> json(%{error: "Failed to fetch media"})
end
end
defp fetch_media(url) do
Tesla.get(url, [
{:timeout, 10_000},
{:max_body_length, @max_body_length}
])
end
defp get_content_type(headers) do
case List.keyfind(headers, "content-type", 0) do
{_, content_type} -> {:ok, content_type}
nil -> {:error, :no_content_type}
end
end
defp validate_mime_type(content_type) do
if Enum.any?(@valid_mime_types, &String.starts_with?(content_type, &1)) do
:ok
else
{:error, :invalid_mime_type}
end
end
end