Code

Ticket #16201: multipartparser_content_length_0.diff

File multipartparser_content_length_0.diff, 2.5 KB (added by albsen, 3 years ago)

patch for multipartparser bug

Line 
1Index: django/http/multipartparser.py
2===================================================================
3--- django/http/multipartparser.py      (revision 16341)
4+++ django/http/multipartparser.py      (working copy)
5@@ -75,7 +75,7 @@
6             # For now set it to 0; we'll try again later on down.
7             content_length = 0
8 
9-        if content_length <= 0:
10+        if content_length < 0:
11             # This means we shouldn't continue...raise an error.
12             raise MultiPartParserError("Invalid content length: %r" % content_length)
13 
14@@ -105,6 +105,11 @@
15         encoding = self._encoding
16         handlers = self._upload_handlers
17 
18+        # HTTP spec says that Content-Length >= 0 is valid
19+        # handling content-length == 0 before continuing
20+        if self._content_length == 0:
21+            return QueryDict(MultiValueDict(), encoding=self._encoding), MultiValueDict()
22+
23         limited_input_data = LimitBytes(self._input_data, self._content_length)
24 
25         # See if the handler will want to take care of the parsing.
26Index: tests/regressiontests/requests/tests.py
27===================================================================
28--- tests/regressiontests/requests/tests.py     (revision 16341)
29+++ tests/regressiontests/requests/tests.py     (working copy)
30@@ -200,6 +200,27 @@
31         self.assertEqual(request.POST, {u'name': [u'value']})
32         self.assertRaises(Exception, lambda: request.raw_post_data)
33 
34+    def test_POST_multipart_with_content_length_zero(self):
35+        """
36+        Multipart POST requests with Content-Length >= 0 are valid and need to be handled.
37+        """
38+        # According to:
39+        # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13
40+        # Every request.POST with Content-Length >= 0 is a valid request,
41+        # this test ensures that we handle Content-Length == 0.
42+        payload = "\r\n".join([
43+                '--boundary',
44+                'Content-Disposition: form-data; name="name"',
45+                '',
46+                'value',
47+                '--boundary--'
48+                ''])
49+        request = WSGIRequest({'REQUEST_METHOD': 'POST',
50+                               'CONTENT_TYPE': 'multipart/form-data; boundary=boundary',
51+                               'CONTENT_LENGTH': 0,
52+                               'wsgi.input': StringIO(payload)})
53+        self.assertEqual(request.POST, {})
54+
55     def test_read_by_lines(self):
56         request = WSGIRequest({'REQUEST_METHOD': 'POST', 'wsgi.input': StringIO('name=value')})
57         self.assertEqual(list(request), ['name=value'])