Ticket #2504: 2504_http_response_and_conditional_middleware.patch

File 2504_http_response_and_conditional_middleware.patch, 4.2 KB (added by Daniel Poelzleithner, 16 years ago)

new patch, fixing the issue with pipes and files

  • django/http/__init__.py

     
    1818class Http404(Exception):
    1919    pass
    2020
     21class UnknownSize(Exception):
     22    pass
     23
    2124class HttpRequest(object):
    2225    "A basic HTTP request"
    2326
     
    314317
    315318    def _get_content(self):
    316319        if self.has_header('Content-Encoding'):
    317             return ''.join(self._container)
    318         return smart_str(''.join(self._container), self._charset)
     320            content = ''.join(self._container)
     321        else:
     322            content = smart_str(''.join(self._container), self._charset)
     323        # cache generated output
     324        self.content = content
     325        return content
    319326
    320327    def _set_content(self, value):
    321328        self._container = [value]
    322329        self._is_string = True
    323330
     331    def get_content_length(self):
     332        # try to determin the length of the file
     333        #
     334        if isinstance(self._container, file):
     335            if os.path.exists(self._container.name):
     336                return os.path.getsize(self._container.name)
     337            else:
     338                raise UnknownSize, "size of file can't be determined"
     339        return len(self.content)
     340
     341
    324342    content = property(_get_content, _set_content)
    325343
    326344    def __iter__(self):
  • django/middleware/http.py

     
    1111    def process_response(self, request, response):
    1212        response['Date'] = http_date()
    1313        if not response.has_header('Content-Length'):
    14             response['Content-Length'] = str(len(response.content))
     14            try:
     15                clength = response.get_content_length()
     16                response['Content-Length'] = str(clength)
     17            except http.UnknownSize:
     18                # FIXME we could switch to chunked transfer encoding if
     19                # self.META['SERVER_PROTOCOL'] == "HTTP/1.1"
     20                # don't sending a Content-Length is legal and EOF
     21                # of tcp connection determins end of stream
     22                pass
    1523
    1624        if response.has_header('ETag'):
    1725            if_none_match = request.META.get('HTTP_IF_NONE_MATCH', None)
  • tests/regressiontests/httpwrappers/tests.py

     
    391391>>> q.getlist('foo')
    392392[u'bar', u'\ufffd']
    393393
     394>>> r = HttpResponse()
     395>>> r.get_content_length()
     3960
     397
     398>>> r = HttpResponse('foo')
     399>>> r.get_content_length()
     4003
     401
     402>>> r = HttpResponse('foo')
     403>>> r.write('bar')
     404>>> r.get_content_length()
     4056
     406
     407>>> r = HttpResponse(['foo', 'bar', 'foobar'])
     408>>> r.get_content_length()
     40912
     410
     411>>> r = HttpResponse(file(__file__))
     412>>> assert r.get_content_length() > 0
     413
     414>>> import os, os.path
     415>>> if os.path.isfile("/bin/echo"):
     416...    fp = os.popen2("echo")
     417...    r = HttpResponse(fp[1])
     418...    r.get_content_length()
     419Traceback (most recent call last):
     420  ...
     421UnknownSize: size of file can't be determined
     422
     423>>> def ten_foos():
     424...     for i in range(10): yield 'foo'
     425
     426>>> r = HttpResponse(ten_foos())
     427>>> r.get_content_length()
     42830
     429>>> print r.content
     430foofoofoofoofoofoofoofoofoofoo
     431
    394432"""
    395433
    396 from django.http import QueryDict
     434from django.http import QueryDict, HttpResponse
    397435
    398436if __name__ == "__main__":
    399437    import doctest
  • docs/request_response.txt

     
    431431``write(content)``, ``flush()`` and ``tell()``
    432432    These methods make an ``HttpResponse`` instance a file-like object.
    433433
     434``get_content_length``
     435    **(New in Django development version)**
     436    Returns the length of the content.
     437    If the content of HttpResponse is a Filepointer to a file, the filesize is returned.
     438    It the Filepointer is a pipe, django.http.UnknownSize exception is raised.
     439
    434440.. _HTTP Status code: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10
    435441
    436442HttpResponse subclasses
Back to Top