Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[1.3.X] Fixed #16201 -- Ensure that requests with Content-Length=0 do…

…n't break the multipart parser. Thanks to albsen for the report and patch

Backport of r16353 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16676 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit e2d7a784c8aa56883a84ba536bc4ba4803fcb94e 1 parent f317bd2
@freakboy3742 freakboy3742 authored
View
7 django/http/multipartparser.py
@@ -75,7 +75,7 @@ def __init__(self, META, input_data, upload_handlers, encoding=None):
# For now set it to 0; we'll try again later on down.
content_length = 0
- if content_length <= 0:
+ if content_length < 0:
# This means we shouldn't continue...raise an error.
raise MultiPartParserError("Invalid content length: %r" % content_length)
@@ -105,6 +105,11 @@ def parse(self):
encoding = self._encoding
handlers = self._upload_handlers
+ # HTTP spec says that Content-Length >= 0 is valid
+ # handling content-length == 0 before continuing
+ if self._content_length == 0:
+ return QueryDict(MultiValueDict(), encoding=self._encoding), MultiValueDict()
+
limited_input_data = LimitBytes(self._input_data, self._content_length)
# See if the handler will want to take care of the parsing.
View
21 tests/regressiontests/requests/tests.py
@@ -200,6 +200,27 @@ def test_raw_post_data_after_POST_multipart(self):
self.assertEqual(request.POST, {u'name': [u'value']})
self.assertRaises(Exception, lambda: request.raw_post_data)
+ def test_POST_multipart_with_content_length_zero(self):
+ """
+ Multipart POST requests with Content-Length >= 0 are valid and need to be handled.
+ """
+ # According to:
+ # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13
+ # Every request.POST with Content-Length >= 0 is a valid request,
+ # this test ensures that we handle Content-Length == 0.
+ payload = "\r\n".join([
+ '--boundary',
+ 'Content-Disposition: form-data; name="name"',
+ '',
+ 'value',
+ '--boundary--'
+ ''])
+ request = WSGIRequest({'REQUEST_METHOD': 'POST',
+ 'CONTENT_TYPE': 'multipart/form-data; boundary=boundary',
+ 'CONTENT_LENGTH': 0,
+ 'wsgi.input': StringIO(payload)})
+ self.assertEqual(request.POST, {})
+
def test_read_by_lines(self):
request = WSGIRequest({'REQUEST_METHOD': 'POST', 'wsgi.input': StringIO('name=value')})
self.assertEqual(list(request), ['name=value'])
Please sign in to comment.
Something went wrong with that request. Please try again.