#29427: RequestDataTooBig raised in request.py prevents Middleware from
returning a
valid response
-----------------------------------------+------------------------
Reporter: S. Paquette | Owner: nobody
Type: Bug | Status: new
Component: HTTP handling | Version: 1.11
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-----------------------------------------+------------------------
This is effectively a request to re-open #28106, which was closed because
the original author never replied to a request for more information.
We need a way to return a response from a Middleware which is handling the
RequestDataTooBig exception, but Middlewares intercepting this exception
never generate a valid response. This seems due to how the exception
causes self._body to never be created in request.py.
In django.http.request, a check of the content length is done against
settings.DATA_UPLOAD_MAX_MEMORY_SIZE at line 267.
{{{
# Limit the maximum request data size that will be handled in-
memory.
if (settings.DATA_UPLOAD_MAX_MEMORY_SIZE is not None and
int(self.META.get('CONTENT_LENGTH') or 0) >
settings.DATA_UPLOAD_MAX_MEMORY_SIZE):
raise RequestDataTooBig('Request body exceeded
settings.DATA_UPLOAD_MAX_MEMORY_SIZE.')
}}}
If the content length exceeds DATA_UPLOAD_MAX_MEMORY_SIZE, no request body
is generated, and a RequestDataTooBig exception is raised.
In order to detect this error and return a useful response to our users'
browsers, we created a Middleware to catch the exception and supply an
informative JsonResponse. However, despite the status setting correctly,
the response itself was never being returned. Our Middleware:
{{{
from django.http import JsonResponse
from django.core.exceptions import RequestDataTooBig
class CheckSize(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
try:
body = request.body
except RequestDataTooBig:
return JsonResponse({"msg": "The file provided is too large.
Please reduce its size and try again."}, status=400)
response = self.get_response(request)
return response
}}}
We tried placing the Middleware anywhere in the chain, and making it the
only Middleware, but nothing worked.
Per the author of #28106, we then added in an empty body to the request
when the exception is raised, and that solved the problem:
{{{
# Limit the maximum request data size that will be handled in-
memory.
if (settings.DATA_UPLOAD_MAX_MEMORY_SIZE is not None and
int(self.META.get('CONTENT_LENGTH') or 0) >
settings.DATA_UPLOAD_MAX_MEMORY_SIZE):
self._body = self.read(None)
raise RequestDataTooBig('Request body exceeded
settings.DATA_UPLOAD_MAX_MEMORY_SIZE.')
}}}
After doing this, our response is returned. This can be reproduced on
Django 1.11.
--
Ticket URL: <https://code.djangoproject.com/ticket/29427>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/053.39c05672e83fd1228c57234d24373b56%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.