diff --git a/README.rst b/README.rst index 5276145a..1b4b82c3 100644 --- a/README.rst +++ b/README.rst @@ -1216,6 +1216,7 @@ Changelog * `0.7.0-dev`_ * Added ``--ignore-stdin``. * Added support for auth plugins. + * Improved ``Content-Disposition`` parsing for ``--download`` mode. * `0.6.0`_ (2013-06-03) * XML data is now formatted. * ``--session`` and ``--session-read-only`` now also accept paths to diff --git a/httpie/downloads.py b/httpie/downloads.py index 5c16cb2a..acce1243 100644 --- a/httpie/downloads.py +++ b/httpie/downloads.py @@ -10,6 +10,7 @@ import sys import mimetypes import threading from time import sleep, time +from mailbox import Message from .output import RawStream from .models import HTTPResponse @@ -104,11 +105,14 @@ def filename_from_content_disposition(content_disposition): """ # attachment; filename=jkbr-httpie-0.4.1-20-g40bd8f6.tar.gz - match = re.search('filename=(\S+)', content_disposition) - if match and match.group(1): - fn = match.group(1).strip('."') - if re.match('^[a-zA-Z0-9._-]+$', fn): - return fn + + msg = Message('Content-Disposition: %s' % content_disposition) + filename = msg.get_filename() + if filename: + # Basic sanitation. + filename = os.path.basename(filename).lstrip('.').strip() + if filename: + return filename def filename_from_url(url, content_type): diff --git a/tests/tests.py b/tests/tests.py index 3cba88e3..a269641c 100755 --- a/tests/tests.py +++ b/tests/tests.py @@ -1562,9 +1562,16 @@ class DownloadUtilsTest(BaseTestCase): parse('attachment; filename=".hello-WORLD_123.txt"'), 'hello-WORLD_123.txt' ) + self.assertEqual( + parse('attachment; filename="white space.txt"'), + 'white space.txt' + ) + self.assertEqual( + parse(r'attachment; filename="\"quotes\".txt"'), + '"quotes".txt' + ) + self.assertEqual(parse('attachment; filename=/etc/hosts'), 'hosts') self.assertIsNone(parse('attachment; filename=')) - self.assertIsNone(parse('attachment; filename=/etc/hosts')) - self.assertIsNone(parse('attachment; filename=hello@world')) def test_filename_from_url(self): self.assertEqual(filename_from_url(