summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorJannis Leidel <jannis@leidel.info>2011-06-28 10:17:56 +0000
committerJannis Leidel <jannis@leidel.info>2011-06-28 10:17:56 +0000
commita6cd78662e72188555027a459cbff2564d72a221 (patch)
treee072e1aed9c6e139fe1c79a4a3f56c80c2a54c80 /django
parent0278947128cf478b47b0bc87ac0c2de0405b3d2a (diff)
Fixed #15785 -- Stopped HttpRequest.read() from reading beyond the end of a wsgi.input stream and removed some redundant code in the multipartparser. Thanks, tomchristie, grahamd and isagalaev.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@16479 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django')
-rw-r--r--django/core/handlers/wsgi.py25
-rw-r--r--django/http/__init__.py12
-rw-r--r--django/http/multipartparser.py36
3 files changed, 11 insertions, 62 deletions
diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py
index 2acb3b1ee7..14420fa760 100644
--- a/django/core/handlers/wsgi.py
+++ b/django/core/handlers/wsgi.py
@@ -135,26 +135,11 @@ class WSGIRequest(http.HttpRequest):
self.META['SCRIPT_NAME'] = script_name
self.method = environ['REQUEST_METHOD'].upper()
self._post_parse_error = False
- if type(socket._fileobject) is type and isinstance(self.environ['wsgi.input'], socket._fileobject):
- # Under development server 'wsgi.input' is an instance of
- # socket._fileobject which hangs indefinitely on reading bytes past
- # available count. To prevent this it's wrapped in LimitedStream
- # that doesn't read past Content-Length bytes.
- #
- # This is not done for other kinds of inputs (like flup's FastCGI
- # streams) beacuse they don't suffer from this problem and we can
- # avoid using another wrapper with its own .read and .readline
- # implementation.
- #
- # The type check is done because for some reason, AppEngine
- # implements _fileobject as a function, not a class.
- try:
- content_length = int(self.environ.get('CONTENT_LENGTH', 0))
- except (ValueError, TypeError):
- content_length = 0
- self._stream = LimitedStream(self.environ['wsgi.input'], content_length)
- else:
- self._stream = self.environ['wsgi.input']
+ try:
+ content_length = int(self.environ.get('CONTENT_LENGTH'))
+ except (ValueError, TypeError):
+ content_length = 0
+ self._stream = LimitedStream(self.environ['wsgi.input'], content_length)
self._read_started = False
def get_full_path(self):
diff --git a/django/http/__init__.py b/django/http/__init__.py
index cf1eb0d9e2..e667f6a9fc 100644
--- a/django/http/__init__.py
+++ b/django/http/__init__.py
@@ -308,17 +308,7 @@ class HttpRequest(object):
if not hasattr(self, '_raw_post_data'):
if self._read_started:
raise Exception("You cannot access raw_post_data after reading from request's data stream")
- try:
- content_length = int(self.META.get('CONTENT_LENGTH', 0))
- except (ValueError, TypeError):
- # If CONTENT_LENGTH was empty string or not an integer, don't
- # error out. We've also seen None passed in here (against all
- # specs, but see ticket #8259), so we handle TypeError as well.
- content_length = 0
- if content_length:
- self._raw_post_data = self.read(content_length)
- else:
- self._raw_post_data = self.read()
+ self._raw_post_data = self.read()
self._stream = StringIO(self._raw_post_data)
return self._raw_post_data
raw_post_data = property(_get_raw_post_data)
diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py
index 63203a4581..477a08c05a 100644
--- a/django/http/multipartparser.py
+++ b/django/http/multipartparser.py
@@ -33,7 +33,7 @@ class MultiPartParser(object):
A rfc2388 multipart/form-data parser.
``MultiValueDict.parse()`` reads the input stream in ``chunk_size`` chunks
- and returns a tuple of ``(MultiValueDict(POST), MultiValueDict(FILES))``. If
+ and returns a tuple of ``(MultiValueDict(POST), MultiValueDict(FILES))``.
"""
def __init__(self, META, input_data, upload_handlers, encoding=None):
"""
@@ -65,14 +65,11 @@ class MultiPartParser(object):
raise MultiPartParserError('Invalid boundary in multipart: %s' % boundary)
- #
# Content-Length should contain the length of the body we are about
# to receive.
- #
try:
content_length = int(META.get('HTTP_CONTENT_LENGTH', META.get('CONTENT_LENGTH',0)))
except (ValueError, TypeError):
- # For now set it to 0; we'll try again later on down.
content_length = 0
if content_length < 0:
@@ -110,12 +107,10 @@ class MultiPartParser(object):
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.
# This allows overriding everything if somebody wants it.
for handler in handlers:
- result = handler.handle_raw_input(limited_input_data,
+ result = handler.handle_raw_input(self._input_data,
self._meta,
self._content_length,
self._boundary,
@@ -128,7 +123,7 @@ class MultiPartParser(object):
self._files = MultiValueDict()
# Instantiate the parser and stream:
- stream = LazyStream(ChunkIter(limited_input_data, self._chunk_size))
+ stream = LazyStream(ChunkIter(self._input_data, self._chunk_size))
# Whether or not to signal a file-completion at the beginning of the loop.
old_field_name = None
@@ -225,10 +220,10 @@ class MultiPartParser(object):
exhaust(stream)
except StopUpload, e:
if not e.connection_reset:
- exhaust(limited_input_data)
+ exhaust(self._input_data)
else:
# Make sure that the request data is all fed
- exhaust(limited_input_data)
+ exhaust(self._input_data)
# Signal that the upload has completed.
for handler in handlers:
@@ -390,27 +385,6 @@ class ChunkIter(object):
def __iter__(self):
return self
-class LimitBytes(object):
- """ Limit bytes for a file object. """
- def __init__(self, fileobject, length):
- self._file = fileobject
- self.remaining = length
-
- def read(self, num_bytes=None):
- """
- Read data from the underlying file.
- If you ask for too much or there isn't anything left,
- this will raise an InputStreamExhausted error.
- """
- if self.remaining <= 0:
- raise InputStreamExhausted()
- if num_bytes is None:
- num_bytes = self.remaining
- else:
- num_bytes = min(num_bytes, self.remaining)
- self.remaining -= num_bytes
- return self._file.read(num_bytes)
-
class InterBoundaryIter(object):
"""
A Producer that will iterate over boundaries.