Commits

mitsuhiko  committed 8727dd2

the multipart parser works better with hand-crafted multipart
requests now that have extra newlines added. This fixes a bug
with setuptools uploades not handled properly (#390)

  • Participants
  • Parent commits b0dca51

Comments (0)

Files changed (4)

 - fixed a bug with the `make_runserver` script action.
 - :meth:`MultiDict.items` and :meth:`MutiDict.iteritems` now accept an
   argument to return a pair for each value of each key.
+- the multipart parser works better with hand-crafted multipart
+  requests now that have extra newlines added.  This fixes a bug
+  with setuptools uploades not handled properly (#390)
 
 
 Version 0.5

File tests/test_parsing.py

 
 
 def test_end_of_file_multipart():
-    """Test for multipart files ending unexpectedly."""
-    # this test looks innocent but it was actually timeing out in
+    """Test for multipart files ending unexpectedly"""
+    # This test looks innocent but it was actually timeing out in
     # the Werkzeug 0.5 release version (#394)
     data = (
         '--foo\r\n'
     assert not data.form
 
 
+def test_extra_newline_multipart():
+    """Test for multipart uploads with extra newlines"""
+    # this test looks innocent but it was actually timeing out in
+    # the Werkzeug 0.5 release version (#394)
+    data = (
+        '\r\n\r\n--foo\r\n'
+        'Content-Disposition: form-data; name="foo"\r\n\r\n'
+        'a string\r\n'
+        '--foo--'
+    )
+    data = Request.from_values(input_stream=StringIO(data),
+                               content_length=len(data),
+                               content_type='multipart/form-data; boundary=foo',
+                               method='POST')
+    assert not data.files
+    assert data.form['foo'] == 'a string'
+
+
 def test_nonstandard_line_endings():
     """Test nonstandard line endings of multipart form data"""
     for nl in '\n', '\r', '\r\n':

File werkzeug/datastructures.py

         >>> d = MultiDict({"foo": [1, 2, 3]})
         >>> zip(d.keys(), d.listvalues()) == d.lists()
         True
-        
+
         :return: a :class:`list`
         """
         return list(self.iterlistvalues())

File werkzeug/http.py

     iterator = chain(make_line_iter(file, buffer_size=buffer_size),
                      repeat(''))
 
+    def _find_terminator():
+        """The terminator might have some additional newlines before it.
+        There is at least one application that sends additional newlines
+        before headers (the python setuptools package).
+        """
+        for line in iterator:
+            if not line:
+                break
+            line = line.strip()
+            if line:
+                return line
+        return ''
+
     try:
-        terminator = iterator.next().strip()
+        terminator = _find_terminator()
         if terminator != next_part:
             raise ValueError('Expected boundary at start of multipart data')