summary refs log tree commit diff
path: root/synapse/rest/media/v1
diff options
context:
space:
mode:
authorMark Haines <mark.haines@matrix.org>2015-08-26 17:08:47 +0100
committerMark Haines <mark.haines@matrix.org>2015-08-26 17:08:47 +0100
commit5a9e0c36824ffc8bb365cdb30a273d427f997bd9 (patch)
tree46fb46d59f912bb559c4cd227e36be7d4df33d9d /synapse/rest/media/v1
parentAllow non-ascii filenames for attachments (diff)
downloadsynapse-5a9e0c36824ffc8bb365cdb30a273d427f997bd9.tar.xz
Handle unicode filenames given when downloading or received over federation
Diffstat (limited to 'synapse/rest/media/v1')
-rw-r--r--synapse/rest/media/v1/base_resource.py26
1 files changed, 21 insertions, 5 deletions
diff --git a/synapse/rest/media/v1/base_resource.py b/synapse/rest/media/v1/base_resource.py
index 24297b20f1..ad2c9d4e74 100644
--- a/synapse/rest/media/v1/base_resource.py
+++ b/synapse/rest/media/v1/base_resource.py
@@ -34,6 +34,7 @@ import os
 import cgi
 import logging
 import urllib
+import urlparse
 
 logger = logging.getLogger(__name__)
 
@@ -43,10 +44,13 @@ def parse_media_id(request):
         # This allows users to append e.g. /test.png to the URL. Useful for
         # clients that parse the URL to see content type.
         server_name, media_id = request.postpath[:2]
-        if len(request.postpath) > 2 and is_ascii(request.postpath[-1]):
-            return server_name, media_id, request.postpath[-1]
-        else:
-            return server_name, media_id, None
+        file_name = None
+        if len(request.postpath) > 2:
+            try:
+                file_name = urlparse.unquote(request.postpath[-1]).decode("utf-8")
+            except UnicodeDecodeError:
+                pass
+        return server_name, media_id, file_name
     except:
         raise SynapseError(
             404,
@@ -144,6 +148,16 @@ class BaseMediaResource(Resource):
                 upload_name = params.get("filename", None)
                 if upload_name and not is_ascii(upload_name):
                     upload_name = None
+                else:
+                    upload_name_utf8 = params.get("filename*", None)
+                    if upload_name_utf8.lower().startswith("utf-8''"):
+                        upload_name = upload_name_utf8[7:]
+                if upload_name:
+                    upload_name = urlparse.unquote(upload_name)
+                    try:
+                        upload_name = upload_name.decode("utf-8");
+                    except UnicodeDecodeError:
+                        upload_name = None
             else:
                 upload_name = None
 
@@ -185,7 +199,9 @@ class BaseMediaResource(Resource):
                 if is_ascii(upload_name):
                     request.setHeader(
                         b"Content-Disposition",
-                        b"inline; filename=%s" % (upload_name.encode("utf-8"),),
+                        b"inline; filename=%s" % (
+                            urllib.quote(upload_name.encode("utf-8")),
+                        ),
                     )
                 else:
                     request.setHeader(