changeset 296:1e9ec607913d

fix downloading of items with non-ascii names (for most modern browsers), implement RFC2231/5987
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Fri, 29 Jul 2011 00:34:24 +0200
parents 72009982fc8d
children 0adc626b1036 e8bd41ab7bdd 201150d3fb89
files MoinMoin/util/
diffstat 1 files changed, 16 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/util/	Fri Jul 22 23:19:50 2011 +0200
+++ b/MoinMoin/util/	Fri Jul 29 00:34:24 2011 +0200
@@ -24,10 +24,21 @@
 from time import time
 from zlib import adler32
-from werkzeug import Headers, wrap_file
+from werkzeug import Headers, wrap_file, url_quote
 from flask import current_app, request
+def encode_rfc2231(value, coding='UTF-8', lang=''):
+    """
+    Encode a value according to RFC2231/5987.
+    :param value: the value to encode. must be either unicode or encoded in <coding>.
+    :param coding: the coding (charset) to use. it is a good idea to use 'UTF-8'.
+    :param lang: the language to use. defaults to empty string (no language given).
+    """
+    return "%s'%s'%s" % (coding, lang, url_quote(value, charset=coding))
 def send_file(filename=None, file=None,
               as_attachment=False, attachment_filename=None,
@@ -107,7 +118,10 @@
             if not filename:
                 raise TypeError('filename unavailable, required for sending as attachment')
             attachment_filename = os.path.basename(filename)
-        headers.add('Content-Disposition', 'attachment', filename=attachment_filename)
+        # Note: we only give filename* param, not filename param, hoping that a user agent that
+        # does not support filename* then falls back into using the last URL fragment (and decodes
+        # that correctly). See there for details:
+        headers.add('Content-Disposition', 'attachment; filename*=%s'% encode_rfc2231(attachment_filename))
     if current_app.use_x_sendfile and filename:
         if file: