forked from mirrors/amputoma
53 lines
1.4 KiB
Elixir
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
|