Ticket #2131: httpresponsesendfile-no-default-content_bypass-middleware.diff

File httpresponsesendfile-no-default-content_bypass-middleware.diff, 7.0 KB (added by mrts, 6 years ago)

Bypass middleware

  • django/http/__init__.py

     
    393393            raise Exception("This %s instance cannot tell its position" % self.__class__)
    394394        return sum([len(chunk) for chunk in self._container])
    395395
     396class HttpResponseSendFile(HttpResponse):
     397    def __init__(self, path_to_file, content_type=None, block_size=8192):
     398        if not content_type:
     399            from mimetypes import guess_type
     400            content_type = guess_type(path_to_file)[0]
     401            if content_type is None:
     402                content_type = "application/octet-stream"
     403        super(HttpResponseSendFile, self).__init__(None,
     404                content_type=content_type)
     405        self.sendfile_filename = path_to_file
     406        self.block_size = block_size
     407        self._headers['content-length'] = ('Content-Length',
     408                os.path.getsize(path_to_file))
     409
    396410class HttpResponseRedirect(HttpResponse):
    397411    status_code = 302
    398412
  • django/core/servers/basehttp.py

     
    313313        in the event loop to iterate over the data, and to call
    314314        'self.close()' once the response is finished.
    315315        """
    316         if not self.result_is_file() and not self.sendfile():
    317             for data in self.result:
    318                 self.write(data)
    319             self.finish_content()
     316        for data in self.result:
     317            self.write(data)
     318        self.finish_content()
    320319        self.close()
    321320
    322321    def get_scheme(self):
  • django/core/handlers/wsgi.py

     
    231231            self.initLock.release()
    232232
    233233        set_script_prefix(base.get_script_name(environ))
    234         signals.request_started.send(sender=self.__class__)
    235         try:
    236             try:
    237                 request = self.request_class(environ)
    238             except UnicodeDecodeError:
    239                 response = http.HttpResponseBadRequest()
    240             else:
    241                 response = self.get_response(request)
    242234
    243                 # Apply response middleware
    244                 for middleware_method in self._response_middleware:
    245                     response = middleware_method(request, response)
    246                 response = self.apply_response_fixes(request, response)
    247         finally:
    248             signals.request_finished.send(sender=self.__class__)
     235        response = self.process_request(req)
    249236
    250237        try:
    251238            status_text = STATUS_CODE_TEXT[response.status_code]
    252239        except KeyError:
    253240            status_text = 'UNKNOWN STATUS CODE'
    254241        status = '%s %s' % (response.status_code, status_text)
     242
    255243        response_headers = [(str(k), str(v)) for k, v in response.items()]
    256244        for c in response.cookies.values():
    257245            response_headers.append(('Set-Cookie', str(c.output(header=''))))
     246
    258247        start_response(status, response_headers)
     248
     249        if isinstance(response, http.HttpResponseSendFile):
     250            filelike = open(response.sendfile_filename, 'rb')
     251            if 'wsgi.file_wrapper' in environ:
     252                return environ['wsgi.file_wrapper'](filelike,
     253                        response.block_size)
     254            else:
     255                # wraps close() as well
     256                from django.core.servers.basehttp import FileWrapper
     257                return FileWrapper(filelike, response.block_size)
     258
    259259        return response
    260260
  • django/core/handlers/base.py

     
    6262        # as a flag for initialization being complete.
    6363        self._request_middleware = request_middleware
    6464
     65    def process_response(self, request_env):
     66        signals.request_started.send(sender=self.__class__)
     67        try:
     68            try:
     69                request = self.request_class(request_env)
     70            except UnicodeDecodeError:
     71                response = http.HttpResponseBadRequest()
     72            else:
     73                response = self.get_response(request)
     74
     75                # Apply response middleware
     76                if not isinstance(response, http.HttpResponseSendFile):
     77                    for middleware_method in self._response_middleware:
     78                        response = middleware_method(request, response)
     79                    response = self.apply_response_fixes(request, response)
     80        finally:
     81            signals.request_finished.send(sender=self.__class__)
     82
     83        return response
     84
    6585    def get_response(self, request):
    6686        "Returns an HttpResponse object for the given HttpRequest"
    6787        from django.core import exceptions, urlresolvers
  • django/core/handlers/modpython.py

     
    22from pprint import pformat
    33
    44from django import http
    5 from django.core import signals
    65from django.core.handlers.base import BaseHandler
    76from django.core.urlresolvers import set_script_prefix
    87from django.utils import datastructures
     
    191190            self.load_middleware()
    192191
    193192        set_script_prefix(req.get_options().get('django.root', ''))
    194         signals.request_started.send(sender=self.__class__)
    195         try:
    196             try:
    197                 request = self.request_class(req)
    198             except UnicodeDecodeError:
    199                 response = http.HttpResponseBadRequest()
    200             else:
    201                 response = self.get_response(request)
    202193
    203                 # Apply response middleware
    204                 for middleware_method in self._response_middleware:
    205                     response = middleware_method(request, response)
    206                 response = self.apply_response_fixes(request, response)
    207         finally:
    208             signals.request_finished.send(sender=self.__class__)
     194        response = self.process_request(req)
    209195
    210196        # Convert our custom HttpResponse object back into the mod_python req.
    211197        req.content_type = response['Content-Type']
     
    215201        for c in response.cookies.values():
    216202            req.headers_out.add('Set-Cookie', c.output(header=''))
    217203        req.status = response.status_code
    218         try:
    219             for chunk in response:
    220                 req.write(chunk)
    221         finally:
    222             response.close()
    223204
     205        if isinstance(response, http.HttpResponseSendFile):
     206            req.sendfile(response.sendfile_filename)
     207        else:
     208            try:
     209                for chunk in response:
     210                    req.write(chunk)
     211            finally:
     212                response.close()
     213
    224214        return 0 # mod_python.apache.OK
    225215
    226216def handler(req):
Back to Top