diff options
| author | href <href@random.sh> | 2017-11-28 21:44:25 +0100 | 
|---|---|---|
| committer | href <href@random.sh> | 2017-11-28 21:44:25 +0100 | 
| commit | 1cb5cbdc6c1cd065e90961a9d538cb72610ae481 (patch) | |
| tree | f2d3c6df992dd695c56454387360148c58b35215 /lib | |
| parent | e28c110eba5a4c8c5b4b3d2f552a8706db511c51 (diff) | |
| download | pleroma-1cb5cbdc6c1cd065e90961a9d538cb72610ae481.tar.gz pleroma-1cb5cbdc6c1cd065e90961a9d538cb72610ae481.zip | |
Improve error handling, add configuration
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/pleroma/web/media_proxy/controller.ex | 55 | ||||
| -rw-r--r-- | lib/pleroma/web/media_proxy/media_proxy.ex | 17 | 
2 files changed, 40 insertions, 32 deletions
| diff --git a/lib/pleroma/web/media_proxy/controller.ex b/lib/pleroma/web/media_proxy/controller.ex index fece7cf45..dc122fc3a 100644 --- a/lib/pleroma/web/media_proxy/controller.ex +++ b/lib/pleroma/web/media_proxy/controller.ex @@ -2,19 +2,27 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyController do    use Pleroma.Web, :controller    require Logger +  @cache_control %{ +    default: "public, max-age=1209600", +    error:   "public, must-revalidate, max-age=160", +  } +    def remote(conn, %{"sig" => sig, "url" => url}) do -    {:ok, url} = Pleroma.Web.MediaProxy.decode_url(sig, url) -    url = url |> URI.encode() -    case proxy_request(url) do -      {:ok, content_type, body} -> -        conn -        |> put_resp_content_type(content_type) -        |> set_cache_header(:default) -        |> send_resp(200, body) -      other -> -        conn -        |> set_cache_header(:error) -        |> redirect(external: url) +    config = Application.get_env(:pleroma, :media_proxy, []) +    with \ +      true <- Keyword.get(config, :enabled, false), +      {:ok, url} <- Pleroma.Web.MediaProxy.decode_url(sig, url), +      url = URI.encode(url), +      {:ok, content_type, body} <- proxy_request(url) +    do +      conn +      |> put_resp_content_type(content_type) +      |> set_cache_header(:default) +      |> send_resp(200, body) +    else +      false -> send_error(conn, 404) +      {:error, :invalid_signature} -> send_error(conn, 403) +      {:error, {:http, _, url}} -> redirect_or_error(conn, url, Keyword.get(config, :redirect_on_failure, true))      end    end @@ -28,21 +36,24 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyController do          {:ok, headers["Content-Type"], body}        {:ok, status, _, _} ->          Logger.warn "MediaProxy: request failed, status #{status}, link: #{link}" -        {:error, :bad_status} +        {:error, {:http, :bad_status, link}}        {:error, error} ->          Logger.warn "MediaProxy: request failed, error #{inspect error}, link: #{link}" -        {:error, error} +        {:error, {:http, error, link}}      end    end -  @cache_control %{ -    default: "public, max-age=1209600", -    error:   "public, must-revalidate, max-age=160", -  } +  defp set_cache_header(conn, key) do +    Plug.Conn.put_resp_header(conn, "cache-control", @cache_control[key]) +  end + +  defp redirect_or_error(conn, url, true), do: redirect(conn, external: url) +  defp redirect_or_error(conn, url, _), do: send_error(conn, 502, "Media proxy error: " <> url) -  defp set_cache_header(conn, true), do: set_cache_header(conn, :default) -  defp set_cache_header(conn, false), do: set_cache_header(conn, :error) -  defp set_cache_header(conn, key) when is_atom(key), do: set_cache_header(conn, @cache_control[key]) -  defp set_cache_header(conn, value) when is_binary(value), do: Plug.Conn.put_resp_header(conn, "cache-control", value) +  defp send_error(conn, code, body \\ "") do +    conn +    |> set_cache_header(:error) +    |> send_resp(code, body) +  end  end diff --git a/lib/pleroma/web/media_proxy/media_proxy.ex b/lib/pleroma/web/media_proxy/media_proxy.ex index 9c1d71748..21ebdfbbc 100644 --- a/lib/pleroma/web/media_proxy/media_proxy.ex +++ b/lib/pleroma/web/media_proxy/media_proxy.ex @@ -1,23 +1,25 @@  defmodule Pleroma.Web.MediaProxy do    @base64_opts [padding: false] -  @base64_key Application.get_env(:pleroma, Pleroma.Web.Endpoint)[:secret_key_base]    def url(nil), do: nil    def url(url) do -    if String.starts_with?(url, Pleroma.Web.base_url) do +    config = Application.get_env(:pleroma, :media_proxy, []) +    if !Keyword.get(config, :enabled, false) or String.starts_with?(url, Pleroma.Web.base_url) do        url      else +      secret = Application.get_env(:pleroma, Pleroma.Web.Endpoint)[:secret_key_base]        base64 = Base.url_encode64(url, @base64_opts) -      sig = :crypto.hmac(:sha, @base64_key, base64) +      sig = :crypto.hmac(:sha, secret, base64)        sig64 = sig |> Base.url_encode64(@base64_opts) -      cache_url("#{sig64}/#{base64}") +      Keyword.get(config, :base_url, Pleroma.Web.base_url) <> "/proxy/#{sig64}/#{base64}"      end    end    def decode_url(sig, url) do +    secret = Application.get_env(:pleroma, Pleroma.Web.Endpoint)[:secret_key_base]      sig = Base.url_decode64!(sig, @base64_opts) -    local_sig = :crypto.hmac(:sha, @base64_key, url) +    local_sig = :crypto.hmac(:sha, secret, url)      if local_sig == sig do        {:ok, Base.url_decode64!(url, @base64_opts)}      else @@ -25,9 +27,4 @@ defmodule Pleroma.Web.MediaProxy do      end    end -  defp cache_url(path) do -    "/proxy/" <> path -  end - -  end | 
