X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Freverse_proxy.ex;h=983e156f53237a2120b92ec0d82fd2b412240c4e;hb=ad5263c647aea65dbeb4c329825671895e0a8863;hp=ad9dc82fe02a653bd9fd3a1272b509b4a5b430d2;hpb=fe2759bc9f2dad044b49f4954693ac09f9368041;p=akkoma diff --git a/lib/pleroma/reverse_proxy.ex b/lib/pleroma/reverse_proxy.ex index ad9dc82fe..983e156f5 100644 --- a/lib/pleroma/reverse_proxy.ex +++ b/lib/pleroma/reverse_proxy.ex @@ -1,8 +1,16 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + defmodule Pleroma.ReverseProxy do - @keep_req_headers ~w(accept user-agent accept-encoding cache-control if-modified-since if-unmodified-since if-none-match if-range range) + alias Pleroma.HTTP + + @keep_req_headers ~w(accept user-agent accept-encoding cache-control if-modified-since) ++ + ~w(if-unmodified-since if-none-match if-range range) @resp_cache_headers ~w(etag date last-modified cache-control) @keep_resp_headers @resp_cache_headers ++ - ~w(content-type content-disposition content-encoding content-range accept-ranges vary) + ~w(content-type content-disposition content-encoding content-range) ++ + ~w(accept-ranges vary) @default_cache_control_header "public, max-age=1209600" @valid_resp_codes [200, 206, 304] @max_read_duration :timer.seconds(30) @@ -53,10 +61,9 @@ defmodule Pleroma.ReverseProxy do * `http`: options for [hackney](https://github.com/benoitc/hackney). """ - @hackney Application.get_env(:pleroma, :hackney, :hackney) - @httpoison Application.get_env(:pleroma, :httpoison, HTTPoison) + @hackney Pleroma.Config.get(:hackney, :hackney) - @default_hackney_options [{:follow_redirect, true}] + @default_hackney_options [] @inline_content_types [ "image/gif", @@ -85,11 +92,13 @@ defmodule Pleroma.ReverseProxy do | {:redirect_on_failure, boolean()} @spec call(Plug.Conn.t(), url :: String.t(), [option()]) :: Plug.Conn.t() - def call(conn = %{method: method}, url, opts \\ []) when method in @methods do + def call(_conn, _url, _opts \\ []) + + def call(conn = %{method: method}, url, opts) when method in @methods do hackney_opts = @default_hackney_options |> Keyword.merge(Keyword.get(opts, :http, [])) - |> @httpoison.process_request_options() + |> HTTP.process_request_options() req_headers = build_req_headers(conn.req_headers, opts) @@ -240,24 +249,23 @@ defmodule Pleroma.ReverseProxy do end defp build_req_headers(headers, opts) do - headers = - headers - |> downcase_headers() - |> Enum.filter(fn {k, _} -> k in @keep_req_headers end) - |> (fn headers -> - headers = headers ++ Keyword.get(opts, :req_headers, []) - - if Keyword.get(opts, :keep_user_agent, false) do - List.keystore( - headers, - "user-agent", - 0, - {"user-agent", Pleroma.Application.user_agent()} - ) - else - headers - end - end).() + headers + |> downcase_headers() + |> Enum.filter(fn {k, _} -> k in @keep_req_headers end) + |> (fn headers -> + headers = headers ++ Keyword.get(opts, :req_headers, []) + + if Keyword.get(opts, :keep_user_agent, false) do + List.keystore( + headers, + "user-agent", + 0, + {"user-agent", Pleroma.Application.user_agent()} + ) + else + headers + end + end).() end defp build_resp_headers(headers, opts) do @@ -268,13 +276,26 @@ defmodule Pleroma.ReverseProxy do |> (fn headers -> headers ++ Keyword.get(opts, :resp_headers, []) end).() end - defp build_resp_cache_headers(headers, opts) do + defp build_resp_cache_headers(headers, _opts) do has_cache? = Enum.any?(headers, fn {k, _} -> k in @resp_cache_headers end) - - if has_cache? do - headers - else - List.keystore(headers, "cache-control", 0, {"cache-control", @default_cache_control_header}) + has_cache_control? = List.keymember?(headers, "cache-control", 0) + + cond do + has_cache? && has_cache_control? -> + headers + + has_cache? -> + # There's caching header present but no cache-control -- we need to explicitely override it + # to public as Plug defaults to "max-age=0, private, must-revalidate" + List.keystore(headers, "cache-control", 0, {"cache-control", "public"}) + + true -> + List.keystore( + headers, + "cache-control", + 0, + {"cache-control", @default_cache_control_header} + ) end end @@ -291,7 +312,25 @@ defmodule Pleroma.ReverseProxy do end if attachment? do - disposition = "attachment; filename=" <> Keyword.get(opts, :attachment_name, "attachment") + name = + try do + {{"content-disposition", content_disposition_string}, _} = + List.keytake(headers, "content-disposition", 0) + + [name | _] = + Regex.run( + ~r/filename="((?:[^"\\]|\\.)*)"/u, + content_disposition_string || "", + capture: :all_but_first + ) + + name + rescue + MatchError -> Keyword.get(opts, :attachment_name, "attachment") + end + + disposition = "attachment; filename=\"#{name}\"" + List.keystore(headers, "content-disposition", 0, {"content-disposition", disposition}) else headers