Fixed #2613 -- Fixed an easily triggered memory error in file uploads for WSGI.

Thanks Jeong-Min Lee.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@3805 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2006-09-23 12:41:19 +00:00
parent 00734bca7e
commit 6a12d767d4
2 changed files with 26 additions and 1 deletions

View File

@ -100,6 +100,7 @@ answer newbie questions, and generally made Django that much better:
lakin.wecker@gmail.com lakin.wecker@gmail.com
Stuart Langridge <http://www.kryogenix.org/> Stuart Langridge <http://www.kryogenix.org/>
Eugene Lazutkin <http://lazutkin.com/blog/> Eugene Lazutkin <http://lazutkin.com/blog/>
Jeong-Min Lee
Christopher Lenz <http://www.cmlenz.net/> Christopher Lenz <http://www.cmlenz.net/>
limodou limodou
Martin Maney <http://www.chipy.org/Martin_Maney> Martin Maney <http://www.chipy.org/Martin_Maney>

View File

@ -4,6 +4,11 @@ from django.dispatch import dispatcher
from django.utils import datastructures from django.utils import datastructures
from django import http from django import http
from pprint import pformat from pprint import pformat
from shutil import copyfileobj
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
# See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html # See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
STATUS_CODE_TEXT = { STATUS_CODE_TEXT = {
@ -50,6 +55,21 @@ STATUS_CODE_TEXT = {
505: 'HTTP VERSION NOT SUPPORTED', 505: 'HTTP VERSION NOT SUPPORTED',
} }
def safe_copyfileobj(fsrc, fdst, length=16*1024, size=0):
"""
A version of shutil.copyfileobj that will not read more than 'size' bytes.
This makes it safe from clients sending more than CONTENT_LENGTH bytes of
data in the body.
"""
if not size:
return copyfileobj(fsrc, fdst, length)
while size > 0:
buf = fsrc.read(min(length, remain))
if not buf:
break
fdst.write(buf)
size -= len(buf)
class WSGIRequest(http.HttpRequest): class WSGIRequest(http.HttpRequest):
def __init__(self, environ): def __init__(self, environ):
self.environ = environ self.environ = environ
@ -119,7 +139,11 @@ class WSGIRequest(http.HttpRequest):
try: try:
return self._raw_post_data return self._raw_post_data
except AttributeError: except AttributeError:
self._raw_post_data = self.environ['wsgi.input'].read(int(self.environ["CONTENT_LENGTH"])) buf = StringIO()
content_length = int(self.environ['CONTENT_LENGTH'])
safe_copyfileobj(self.environ['wsgi.input'], buf, size=content_length)
self._raw_post_data = buf.getvalue()
buf.close()
return self._raw_post_data return self._raw_post_data
GET = property(_get_get, _set_get) GET = property(_get_get, _set_get)