Merge branch 'changelog/adminfe' into 'develop'
[akkoma] / lib / pleroma / reverse_proxy.ex
index a25b5ea4e16f0af9c804d65a53a4fd4a7afd3fd4..a3f177fec06d4ea8ab3da7e41d9a159663ca02ff 100644 (file)
@@ -3,10 +3,12 @@
 # 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)
+  @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)
@@ -282,8 +284,8 @@ defmodule Pleroma.ReverseProxy do
         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"
+        # 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 ->
@@ -309,7 +311,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