Opened 4 years ago

Closed 4 years ago

Last modified 3 years ago

#28106 closed Bug (needsinfo)

Broken response/request after raising RequestDataTooBig in request.py

Reported by: Andrew Owned by: nobody
Component: HTTP handling Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Andrew)

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

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.

Change History (8)

comment:1 Changed 4 years ago by Andrew

Description: modified (diff)

comment:2 Changed 4 years ago by Andrew

Component: UncategorizedHTTP handling
Has patch: set

comment:3 Changed 4 years ago by Andrew

Type: UncategorizedBug

comment:4 Changed 4 years ago by Andrew

Description: modified (diff)

comment:5 Changed 4 years ago by Andrew

Version: 1.10master

comment:6 Changed 4 years ago by Tim Graham

I'm not able to reproduce the issue with the information you provided. Could you provide a sample project or a test for Django's test suite?

comment:7 Changed 4 years ago by Tim Graham

Resolution: needsinfo
Status: newclosed

comment:8 Changed 3 years ago by Tim Graham

#29427 is a duplicate that's been accepted.

Note: See TracTickets for help on using tickets.
Back to Top