diff --git a/peru/resources/plugins/curl/curl_plugin.py b/peru/resources/plugins/curl/curl_plugin.py index cc956cd..5fd04e3 100755 --- a/peru/resources/plugins/curl/curl_plugin.py +++ b/peru/resources/plugins/curl/curl_plugin.py @@ -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' diff --git a/tests/test_curl_plugin.py b/tests/test_curl_plugin.py index 1d83f5d..0957cca 100644 --- a/tests/test_curl_plugin.py +++ b/tests/test_curl_plugin.py @@ -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