Browse Source

Always set the filename in Content-Disposition

Relates to original fix for #1158
John-Scott Atlakson 3 years ago
parent
commit
4a7fb00d35
4 changed files with 21 additions and 17 deletions
  1. 1 0
      CHANGELOG.txt
  2. 1 0
      docs/releases/2.17.md
  3. 4 1
      wagtail/documents/tests/test_views.py
  4. 15 16
      wagtail/utils/sendfile.py

+ 1 - 0
CHANGELOG.txt

@@ -15,6 +15,7 @@ Changelog
  * Remove IE11 warnings (Gianluca De Cola)
  * Fix: When using `simple_translations` ensure that the user is redirected to the page edit view when submitting for a single locale (Mitchel Cabuloy)
  * Fix: When previewing unsaved changes to `Form` pages, ensure that all added fields are correctly shown in the preview (Joshua Munn)
+ * Fix: When Documents (e.g. PDFs) have been configured to be served inline via `WAGTAILDOCS_CONTENT_TYPES` & `WAGTAILDOCS_INLINE_CONTENT_TYPES` ensure that the filename is correctly set in the `Content-Disposition` header so that saving the files will use the correct filename (John-Scott Atlakson)
 
 
 2.16.2 (xx.xx.xxxx) - IN DEVELOPMENT

+ 1 - 0
docs/releases/2.17.md

@@ -31,6 +31,7 @@ Here are other changes related to the redesign:
  * Update django-treebeard dependency to 4.5.1 or above (Serafeim Papastefanos)
  * When using `simple_translations` ensure that the user is redirected to the page edit view when submitting for a single locale (Mitchel Cabuloy)
  * When previewing unsaved changes to `Form` pages, ensure that all added fields are correctly shown in the preview (Joshua Munn)
+ * When Documents (e.g. PDFs) have been configured to be served inline via `WAGTAILDOCS_CONTENT_TYPES` & `WAGTAILDOCS_INLINE_CONTENT_TYPES` ensure that the filename is correctly set in the `Content-Disposition` header so that saving the files will use the correct filename (John-Scott Atlakson)
 
 
 ## Upgrade considerations

+ 4 - 1
wagtail/documents/tests/test_views.py

@@ -53,7 +53,10 @@ class TestServeView(TestCase):
         )
 
     def test_inline_content_disposition_header(self):
-        self.assertEqual(self.get(self.pdf_document)["Content-Disposition"], "inline")
+        self.assertEqual(
+            self.get(self.pdf_document)["Content-Disposition"],
+            'inline; filename="{}"'.format(self.pdf_document.filename),
+        )
 
     @mock.patch("wagtail.documents.views.serve.hooks")
     @mock.patch("wagtail.documents.views.serve.get_object_or_404")

+ 15 - 16
wagtail/utils/sendfile.py

@@ -78,28 +78,27 @@ def sendfile(
 
     response = _sendfile(request, filename, mimetype=mimetype)
     if attachment:
-        if attachment_filename is None:
-            attachment_filename = os.path.basename(filename)
         parts = ["attachment"]
-        if attachment_filename:
-            from django.utils.encoding import force_str
-
-            from wagtail.core.utils import string_to_ascii
+    else:
+        parts = ["inline"]
+    if attachment_filename is None:
+        attachment_filename = os.path.basename(filename)
+    if attachment_filename:
+        from django.utils.encoding import force_str
 
-            attachment_filename = force_str(attachment_filename)
-            ascii_filename = string_to_ascii(attachment_filename)
-            parts.append('filename="%s"' % ascii_filename)
+        from wagtail.core.utils import string_to_ascii
 
-            if ascii_filename != attachment_filename:
-                from urllib.parse import quote
+        attachment_filename = force_str(attachment_filename)
+        ascii_filename = string_to_ascii(attachment_filename)
+        parts.append('filename="%s"' % ascii_filename)
 
-                quoted_filename = quote(attachment_filename)
-                parts.append("filename*=UTF-8''%s" % quoted_filename)
+        if ascii_filename != attachment_filename:
+            from urllib.parse import quote
 
-        response["Content-Disposition"] = "; ".join(parts)
-    else:
-        response["Content-Disposition"] = "inline"
+            quoted_filename = quote(attachment_filename)
+            parts.append("filename*=UTF-8''%s" % quoted_filename)
 
+    response["Content-Disposition"] = "; ".join(parts)
     response["Content-length"] = os.path.getsize(filename)
     response["Content-Type"] = mimetype
     response["Content-Encoding"] = encoding or guessed_encoding