Ticket #2504: get_content_length2.diff

File get_content_length2.diff, 4.6 KB (added by Fraser Nevett, 17 years ago)

Supercedes get_content_length.diff

  • django/http/__init__.py

     
    240240        if not content_type:
    241241            content_type = "%s; charset=%s" % (settings.DEFAULT_CONTENT_TYPE,
    242242                    settings.DEFAULT_CHARSET)
    243         if not isinstance(content, basestring) and hasattr(content, '__iter__'):
     243        self._is_file = False
     244        if isinstance(content, file):
    244245            self._container = content
    245             self._is_string = False
     246            self._is_file = True
     247        elif not isinstance(content, basestring) and hasattr(content, '__iter__'):
     248            self._container = list(content)
    246249        else:
    247250            self._container = [content]
    248             self._is_string = True
    249251        self._headers = {'content-type': content_type}
    250252        self.cookies = SimpleCookie()
    251253        if status:
     
    299301
    300302    def _get_content(self):
    301303        content = smart_str(''.join(self._container), self._charset)
     304        self.content = content
    302305        return content
    303306
    304307    def _set_content(self, value):
    305308        self._container = [value]
    306         self._is_string = True
     309        self._is_file = False
    307310
    308311    content = property(_get_content, _set_content)
    309312
     313    def get_content_length(self):
     314        if isinstance(self._container, file):
     315            if os.path.exists(self._container.name):
     316                return os.path.getsize(self._container.name)
     317        return len(self.content)
     318
    310319    def __iter__(self):
    311320        self._iterator = iter(self._container)
    312321        return self
     
    324333    # The remaining methods partially implement the file-like object interface.
    325334    # See http://docs.python.org/lib/bltin-file-objects.html
    326335    def write(self, content):
    327         if not self._is_string:
     336        if self._is_file:
    328337            raise Exception, "This %s instance is not writable" % self.__class__
    329338        self._container.append(content)
    330339
     
    332341        pass
    333342
    334343    def tell(self):
    335         if not self._is_string:
     344        if self._is_file:
    336345            raise Exception, "This %s instance cannot tell its position" % self.__class__
    337346        return sum([len(chunk) for chunk in self._container])
    338347
  • django/middleware/http.py

     
    1313    def process_response(self, request, response):
    1414        response['Date'] = formatdate()[:26] + "GMT"
    1515        if not response.has_header('Content-Length'):
    16             response['Content-Length'] = str(len(response.content))
     16            content_length = response.get_content_length()
     17            if content_length is not None:
     18                response['Content-Length'] = str(content_length)
    1719
    1820        if response.has_header('ETag'):
    1921            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
     395>>> r = HttpResponse()
     396>>> r.get_content_length()
     3970
     398
     399>>> r = HttpResponse('foo')
     400>>> r.get_content_length()
     4013
     402
     403>>> r = HttpResponse('foo')
     404>>> r.write('bar')
     405>>> r.get_content_length()
     4066
     407
     408>>> r = HttpResponse(['foo', 'bar', 'foobar'])
     409>>> r.get_content_length()
     41012
     411
     412>>> r = HttpResponse(file(__file__))
     413>>> assert r.get_content_length() > 0
     414
     415>>> def ten_foos():
     416...     for i in range(10): yield 'foo'
     417>>> r = HttpResponse(ten_foos())
     418>>> r.get_content_length()
     41930
     420>>> print r.content
     421foofoofoofoofoofoofoofoofoofoo
     422
    394423"""
    395424
    396 from django.http import QueryDict
     425from django.http import QueryDict, HttpResponse
    397426
    398427if __name__ == "__main__":
    399428    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    Returns the current length of ``content``.
     436
    434437.. _HTTP Status code: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10
    435438
    436439HttpResponse subclasses
Back to Top