From: Ivan Tashkinov Date: Thu, 2 Jul 2020 13:36:54 +0000 (+0300) Subject: Merge remote-tracking branch 'remotes/origin/develop' into 2168-media-preview-proxy X-Git-Url: http://git.squeep.com/?a=commitdiff_plain;h=61180ab6f4b85ab78de2eaf1bc1b974c9e7908af;p=akkoma Merge remote-tracking branch 'remotes/origin/develop' into 2168-media-preview-proxy # Conflicts: # config/config.exs # lib/pleroma/web/media_proxy/media_proxy.ex # lib/pleroma/web/media_proxy/media_proxy_controller.ex --- 61180ab6f4b85ab78de2eaf1bc1b974c9e7908af diff --cc config/config.exs index d1440b7bf,9b550920c..c8b6c7fad --- a/config/config.exs +++ b/config/config.exs @@@ -393,16 -405,13 +407,23 @@@ config :pleroma, :media_proxy ], whitelist: [] + config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Http, + method: :purge, + headers: [], + options: [] + + config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Script, script_path: nil + +# Note: media preview proxy depends on media proxy to be enabled +config :pleroma, :media_preview_proxy, + enabled: false, + thumbnail_max_width: 400, + thumbnail_max_height: 200, + proxy_opts: [ + head_request_max_read_duration: 5_000, + max_read_duration: 10_000 + ] + config :pleroma, :chat, enabled: true config :phoenix, :format_encoders, json: Jason @@@ -681,10 -696,15 +708,19 @@@ config :pleroma, :restrict_unauthentica config :pleroma, Pleroma.Web.ApiSpec.CastAndValidate, strict: false + config :pleroma, :mrf, + policies: Pleroma.Web.ActivityPub.MRF.NoOpPolicy, + transparency: true, + transparency_exclusions: [] + + config :tzdata, :http_client, Pleroma.HTTP.Tzdata + + config :ex_aws, http_client: Pleroma.HTTP.ExAws + +config :pleroma, :exexec, + root_mode: false, + options: %{} + # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. import_config "#{Mix.env()}.exs" diff --cc lib/pleroma/web/media_proxy/media_proxy.ex index 4e01c14e4,077fabe47..1b6242cb4 --- a/lib/pleroma/web/media_proxy/media_proxy.ex +++ b/lib/pleroma/web/media_proxy/media_proxy.ex @@@ -13,32 -37,27 +37,41 @@@ defmodule Pleroma.Web.MediaProxy d def url("/" <> _ = url), do: url def url(url) do - if not enabled?() or local?(url) or whitelisted?(url) do - if disabled?() or not url_proxiable?(url) do ++ if not enabled?() or not url_proxiable?(url) do url else encode_url(url) end end + @spec url_proxiable?(String.t()) :: boolean() + def url_proxiable?(url) do + if local?(url) or whitelisted?(url) do + false + else + true + end + end + - defp disabled?, do: !Config.get([:media_proxy, :enabled], false) + # Note: routing all URLs to preview handler (even local and whitelisted). + # Preview handler will call url/1 on decoded URLs, and applicable ones will detour media proxy. + def preview_url(url) do + if preview_enabled?() do + encode_preview_url(url) + else + url + end + end - defp local?(url), do: String.starts_with?(url, Pleroma.Web.base_url()) + def enabled?, do: Config.get([:media_proxy, :enabled], false) - defp whitelisted?(url) do + # Note: media proxy must be enabled for media preview proxy in order to load all + # non-local non-whitelisted URLs through it and be sure that body size constraint is preserved. + def preview_enabled?, do: enabled?() and Config.get([:media_preview_proxy, :enabled], false) + + def local?(url), do: String.starts_with?(url, Pleroma.Web.base_url()) + + def whitelisted?(url) do %{host: domain} = URI.parse(url) mediaproxy_whitelist = Config.get([:media_proxy, :whitelist]) diff --cc lib/pleroma/web/media_proxy/media_proxy_controller.ex index 12d4401fa,9a64b0ef3..0f4575e2f --- a/lib/pleroma/web/media_proxy/media_proxy_controller.ex +++ b/lib/pleroma/web/media_proxy/media_proxy_controller.ex @@@ -10,16 -8,19 +10,20 @@@ defmodule Pleroma.Web.MediaProxy.MediaP alias Pleroma.ReverseProxy alias Pleroma.Web.MediaProxy - @default_proxy_opts [max_body_length: 25 * 1_048_576, http: [follow_redirect: true]] - - def remote(conn, %{"sig" => sig64, "url" => url64} = params) do - with config <- Pleroma.Config.get([:media_proxy], []), - true <- Keyword.get(config, :enabled, false), - {:ok, url} <- MediaProxy.decode_url(sig64, url64), + def remote(conn, %{"sig" => sig64, "url" => url64}) do + with {_, true} <- {:enabled, MediaProxy.enabled?()}, + {_, false} <- {:in_banned_urls, MediaProxy.in_banned_urls(url)}, - :ok <- filename_matches(params, conn.request_path, url) do - ReverseProxy.call(conn, url, Keyword.get(config, :proxy_opts, @default_proxy_opts)) + {:ok, url} <- MediaProxy.decode_url(sig64, url64), + :ok <- MediaProxy.verify_request_path_and_url(conn, url) do + proxy_opts = Config.get([:media_proxy, :proxy_opts], []) + ReverseProxy.call(conn, url, proxy_opts) else - error when error in [false, {:in_banned_urls, true}] -> + {:enabled, false} -> + send_resp(conn, 404, Plug.Conn.Status.reason_phrase(404)) + ++ {:in_banned_urls, true} -> + send_resp(conn, 404, Plug.Conn.Status.reason_phrase(404)) + {:error, :invalid_signature} -> send_resp(conn, 403, Plug.Conn.Status.reason_phrase(403))