mirror of https://github.com/pallets/flask.git
encode filenames as ascii instead of latin-1
latin-1 is allowed by pep3333, but that breaks gunicorn
This commit is contained in:
parent
401d7f9bb2
commit
b51ab3ff2c
|
@ -9,6 +9,12 @@ Version 1.0.3
|
||||||
|
|
||||||
Unreleased
|
Unreleased
|
||||||
|
|
||||||
|
- :func:`send_file` encodes filenames as ASCII instead of Latin-1
|
||||||
|
(ISO-8859-1). This fixes compatibility with Gunicorn, which is
|
||||||
|
stricter about header encodings than PEP 3333. (`#2766`_)
|
||||||
|
|
||||||
|
.. _#2766: https://github.com/pallets/flask/issues/2766
|
||||||
|
|
||||||
|
|
||||||
Version 1.0.2
|
Version 1.0.2
|
||||||
-------------
|
-------------
|
||||||
|
|
|
@ -506,6 +506,10 @@ def send_file(filename_or_fp, mimetype=None, as_attachment=False,
|
||||||
|
|
||||||
.. _RFC 2231: https://tools.ietf.org/html/rfc2231#section-4
|
.. _RFC 2231: https://tools.ietf.org/html/rfc2231#section-4
|
||||||
|
|
||||||
|
.. versionchanged:: 1.0.3
|
||||||
|
Filenames are encoded with ASCII instead of Latin-1 for broader
|
||||||
|
compatibility with WSGI servers.
|
||||||
|
|
||||||
:param filename_or_fp: the filename of the file to send.
|
:param filename_or_fp: the filename of the file to send.
|
||||||
This is relative to the :attr:`~Flask.root_path`
|
This is relative to the :attr:`~Flask.root_path`
|
||||||
if a relative path is specified.
|
if a relative path is specified.
|
||||||
|
@ -564,11 +568,11 @@ def send_file(filename_or_fp, mimetype=None, as_attachment=False,
|
||||||
'sending as attachment')
|
'sending as attachment')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
attachment_filename = attachment_filename.encode('latin-1')
|
attachment_filename = attachment_filename.encode('ascii')
|
||||||
except UnicodeEncodeError:
|
except UnicodeEncodeError:
|
||||||
filenames = {
|
filenames = {
|
||||||
'filename': unicodedata.normalize(
|
'filename': unicodedata.normalize(
|
||||||
'NFKD', attachment_filename).encode('latin-1', 'ignore'),
|
'NFKD', attachment_filename).encode('ascii', 'ignore'),
|
||||||
'filename*': "UTF-8''%s" % url_quote(attachment_filename),
|
'filename*': "UTF-8''%s" % url_quote(attachment_filename),
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -638,15 +638,22 @@ class TestSendfile(object):
|
||||||
assert options['filename'] == 'index.txt'
|
assert options['filename'] == 'index.txt'
|
||||||
rv.close()
|
rv.close()
|
||||||
|
|
||||||
def test_attachment_with_utf8_filename(self, app, req_ctx):
|
@pytest.mark.usefixtures('req_ctx')
|
||||||
rv = flask.send_file('static/index.html', as_attachment=True, attachment_filename=u'Ñandú/pingüino.txt')
|
@pytest.mark.parametrize(('filename', 'ascii', 'utf8'), (
|
||||||
content_disposition = set(rv.headers['Content-Disposition'].split('; '))
|
('index.html', 'index.html', False),
|
||||||
assert content_disposition == set((
|
(u'Ñandú/pingüino.txt', '"Nandu/pinguino.txt"',
|
||||||
'attachment',
|
'%C3%91and%C3%BA%EF%BC%8Fping%C3%BCino.txt'),
|
||||||
'filename="Nandu/pinguino.txt"',
|
(u'Vögel.txt', 'Vogel.txt', 'V%C3%B6gel.txt'),
|
||||||
"filename*=UTF-8''%C3%91and%C3%BA%EF%BC%8Fping%C3%BCino.txt"
|
))
|
||||||
))
|
def test_attachment_filename_encoding(self, filename, ascii, utf8):
|
||||||
|
rv = flask.send_file('static/index.html', as_attachment=True, attachment_filename=filename)
|
||||||
rv.close()
|
rv.close()
|
||||||
|
content_disposition = rv.headers['Content-Disposition']
|
||||||
|
assert 'filename=%s' % ascii in content_disposition
|
||||||
|
if utf8:
|
||||||
|
assert "filename*=UTF-8''" + utf8 in content_disposition
|
||||||
|
else:
|
||||||
|
assert "filename*=UTF-8''" not in content_disposition
|
||||||
|
|
||||||
def test_static_file(self, app, req_ctx):
|
def test_static_file(self, app, req_ctx):
|
||||||
# default cache timeout is 12 hours
|
# default cache timeout is 12 hours
|
||||||
|
|
Loading…
Reference in New Issue