#28106: Broken response/request after raising RequestDataTooBig in request.py
-------------------------------+--------------------------------------
Reporter: Andrew | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 1.10
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Description changed by Andrew:
Old description:
> I have a middleware where I want to catch RequestDataTooBig exeption,
> process it and return a valid response to the user.
> However, browser can not see response, though django says response was
> sent.
>
> To be more precise:
> middleware:
>
> {{{
> from django.http import JsonResponse, HttpResponse
> from django.shortcuts import render
> from django.core.exceptions import RequestDataTooBig
>
> class CheckRequest(object):
>
> def __init__(self, get_response):
> print('middleware init')
> self.get_response = get_response
>
> def __call__(self, request):
> print('middleware call')
>
> response = self.get_response(request)
>
> return response
>
> def process_exception(self, request, exception):
> print('middleware process exeption', exception)
> if isinstance(exception, RequestDataTooBig):
> print('CALLED')
> return HttpResponse("dummy", content_type="text/plain")
> #return JsonResponse({"error":"file is too big"})
> }}}
>
> Browser:
> "Failed to load response data"
>
> I did some research and found out that if I add one line to
> https://github.com/django/django/blob/master/django/http/request.py
>
> (create _body to the object before raise) everything starts work as
> supposed - I get correct response in browser.
>
> {{{
> @property
> def body(self):
> if not hasattr(self, '_body'):
> if self._read_started:
> raise RawPostDataException("You cannot access body after
> reading from request's data stream")
>
> self._body = self.read(None) # <------ THIS ONE
> # 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.')
>
> try:
> self._body = self.read()
> except IOError as e:
> six.reraise(UnreadablePostError,
> UnreadablePostError(*e.args), sys.exc_info()[2])
> self._stream = BytesIO(self._body)
> return self._body
> }}}
>
> I do not think it's a right solution, and I may by totally wrong, but it
> seems that either response or request object becomes invalid when this
> exception is raised.
>
> I left logs and pics at stackoverflow
> http://stackoverflow.com/questions/43496658/django-catch-
> requestdatatoobig-exception/43528969#43528969, and can add additional
> information if needed.
>
> To make long story short, you can not send valid response if this
> exception was raised.
New description:
I have a middleware where I want to catch RequestDataTooBig exeption,
process it and return a valid response to the user.
However, browser can not see response, though django says response was
sent.
To be more precise:
middleware:
{{{
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render
from django.core.exceptions import RequestDataTooBig
class CheckRequest(object):
def __init__(self, get_response):
print('middleware init')
self.get_response = get_response
def __call__(self, request):
print('middleware call')
response = self.get_response(request)
return response
def process_exception(self, request, exception):
print('middleware process exeption', exception)
if isinstance(exception, RequestDataTooBig):
print('CALLED')
return HttpResponse("dummy", content_type="text/plain")
#return JsonResponse({"error":"file is too big"})
}}}
Browser:
"Failed to load response data"
I did some research and found out that if I add one line to
https://github.com/django/django/blob/master/django/http/request.py
(create _body to the object before raise) everything starts work as
supposed - I get correct response in browser.
{{{
@property
def body(self):
if not hasattr(self, '_body'):
if self._read_started:
raise RawPostDataException("You cannot access body after
reading from request's data stream")
# 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) # <------ THIS ONE
raise RequestDataTooBig('Request body exceeded
settings.DATA_UPLOAD_MAX_MEMORY_SIZE.')
try:
self._body = self.read()
except IOError as e:
six.reraise(UnreadablePostError,
UnreadablePostError(*e.args), sys.exc_info()[2])
self._stream = BytesIO(self._body)
return self._body
}}}
I do not think it's a right solution, and I may by totally wrong, but it
seems that either response or request object becomes invalid when this
exception is raised.
I left logs and pics at stackoverflow
http://stackoverflow.com/questions/43496658/django-catch-
requestdatatoobig-exception/43528969#43528969, and can add additional
information if needed.
To make long story short, you can not send valid response if this
exception was raised.
--
--
Ticket URL: <https://code.djangoproject.com/ticket/28106#comment:1>
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/066.82c8068ac2d139ff916f43ad7f0b364b%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.