Author: lukeplant
Date: 2011-03-28 09:15:43 -0700 (Mon, 28 Mar 2011)
New Revision: 15939
Modified:
django/branches/releases/1.3.X/django/http/__init__.py
django/branches/releases/1.3.X/tests/regressiontests/requests/tests.py
Log:
[1.3.X] Fixed #15679 - regression in HttpRequest.POST and raw_post_data access.
Thanks to vkryachko for the report.
This also fixes a slight inconsistency with raw_post_data after parsing of a
multipart request, and adds a test for that. (Previously accessing
raw_post_data would have returned the empty string rather than raising an
Exception).
Backport of [15938] from trunk.
Modified: django/branches/releases/1.3.X/django/http/__init__.py
===================================================================
--- django/branches/releases/1.3.X/django/http/__init__.py 2011-03-28
16:11:40 UTC (rev 15938)
+++ django/branches/releases/1.3.X/django/http/__init__.py 2011-03-28
16:15:43 UTC (rev 15939)
@@ -262,14 +262,18 @@
if self.method != 'POST':
self._post, self._files = QueryDict('', encoding=self._encoding),
MultiValueDict()
return
- if self._read_started:
+ if self._read_started and not hasattr(self, '_raw_post_data'):
self._mark_post_parse_error()
return
if self.META.get('CONTENT_TYPE', '').startswith('multipart'):
- self._raw_post_data = ''
+ if hasattr(self, '_raw_post_data'):
+ # Use already read data
+ data = StringIO(self._raw_post_data)
+ else:
+ data = self
try:
- self._post, self._files = self.parse_file_upload(self.META,
self)
+ self._post, self._files = self.parse_file_upload(self.META,
data)
except:
# An error occured while parsing POST data. Since when
# formatting the error the request handler might access
Modified: django/branches/releases/1.3.X/tests/regressiontests/requests/tests.py
===================================================================
--- django/branches/releases/1.3.X/tests/regressiontests/requests/tests.py
2011-03-28 16:11:40 UTC (rev 15938)
+++ django/branches/releases/1.3.X/tests/regressiontests/requests/tests.py
2011-03-28 16:15:43 UTC (rev 15939)
@@ -179,6 +179,66 @@
self.assertRaises(Exception, lambda: request.raw_post_data)
self.assertEqual(request.POST, {})
+ def test_raw_post_data_after_POST_multipart(self):
+ """
+ Reading raw_post_data after parsing multipart is not allowed
+ """
+ # Because multipart is used for large amounts fo data i.e. file
uploads,
+ # we don't want the data held in memory twice, and we don't want to
+ # silence the error by setting raw_post_data = '' either.
+ 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': len(payload),
+ 'wsgi.input': StringIO(payload)})
+ self.assertEqual(request.POST, {u'name': [u'value']})
+ self.assertRaises(Exception, lambda: request.raw_post_data)
+
def test_read_by_lines(self):
request = WSGIRequest({'REQUEST_METHOD': 'POST', 'wsgi.input':
StringIO('name=value')})
self.assertEqual(list(request), ['name=value'])
+
+ def test_POST_after_raw_post_data_read(self):
+ """
+ POST should be populated even if raw_post_data is read first
+ """
+ request = WSGIRequest({'REQUEST_METHOD': 'POST', 'wsgi.input':
StringIO('name=value')})
+ raw_data = request.raw_post_data
+ self.assertEqual(request.POST, {u'name': [u'value']})
+
+ def test_POST_after_raw_post_data_read_and_stream_read(self):
+ """
+ POST should be populated even if raw_post_data is read first, and then
+ the stream is read second.
+ """
+ request = WSGIRequest({'REQUEST_METHOD': 'POST', 'wsgi.input':
StringIO('name=value')})
+ raw_data = request.raw_post_data
+ self.assertEqual(request.read(1), u'n')
+ self.assertEqual(request.POST, {u'name': [u'value']})
+
+ def test_POST_after_raw_post_data_read_and_stream_read_multipart(self):
+ """
+ POST should be populated even if raw_post_data is read first, and then
+ the stream is read second. Using multipart/form-data instead of
urlencoded.
+ """
+ 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': len(payload),
+ 'wsgi.input': StringIO(payload)})
+ raw_data = request.raw_post_data
+ # Consume enough data to mess up the parsing:
+ self.assertEqual(request.read(13), u'--boundary\r\nC')
+ self.assertEqual(request.POST, {u'name': [u'value']})
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en.