handle quotes in Content-Disposition filenames

Summary:
The HTTP standard specifies
(http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1) that
`Content-Disposition` filenames can be quoted. I forgot to handle that.

Closes https://github.com/buildinspace/peru/issues/70.

Test Plan: Add a couple extra cases to the existing test.

Reviewers: sean

Reviewed By: sean

Differential Revision: https://phabricator.buildinspace.com/D144
This commit is contained in:
Jack O'Connor 2014-12-17 17:40:12 -08:00
parent f91dd4c936
commit a265b26e41
2 changed files with 19 additions and 1 deletions

View File

@ -16,7 +16,15 @@ def get_request_filename(request):
pieces = re.split('\s*;\s*', disposition)
for piece in pieces:
if piece.startswith('filename='):
return piece[len('filename='):]
filename = piece[len('filename='):]
# Strip exactly one " from each end.
if filename.startswith('"'):
filename = filename[1:]
if filename.endswith('"'):
filename = filename[:-1]
# Interpret backslashed quotes.
filename = filename.replace('\\"', '"')
return filename
# If no filename was specified, pick a reasonable default.
return os.path.basename(urlsplit(request.url).path) or 'index.html'

View File

@ -46,6 +46,16 @@ class CurlPluginTest(unittest.TestCase):
'attachment; filename=bar'}
self.assertEqual('bar',
curl_plugin.get_request_filename(request))
# Check quoted filenames.
request._info = {'Content-Disposition':
'attachment; filename="bar"'}
self.assertEqual('bar',
curl_plugin.get_request_filename(request))
# Check backslashed quotes in filenames.
request._info = {'Content-Disposition':
'attachment; filename="bar\\""'}
self.assertEqual('bar"',
curl_plugin.get_request_filename(request))
def test_download_file_with_length(self):
content = b'xy' * 4096