mirror of
https://github.com/django/django.git
synced 2025-07-04 01:39:20 +00:00
[soc2009/http-wsgi-improvements] Expects content to be iterable throughout `HttpResponse
`, with regression tests. HttpResponse.close() is now a no-op. Thanks daonb and stugots!
Passes the test suite. git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/http-wsgi-improvements@11262 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
3e5ab0b8ec
commit
88b1183425
1
AUTHORS
1
AUTHORS
@ -121,6 +121,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
Matt Dennenbaum
|
||||
deric@monowerks.com
|
||||
Max Derkachev <mderk@yandex.ru>
|
||||
John DeRosa <stugots@qwest.net>
|
||||
Rajesh Dhawan <rajesh.dhawan@gmail.com>
|
||||
Sander Dijkhuis <sander.dijkhuis@gmail.com>
|
||||
Jordan Dimov <s3x3y1@gmail.com>
|
||||
|
@ -275,7 +275,7 @@ class HttpResponse(object):
|
||||
_charset = settings.DEFAULT_CHARSET
|
||||
|
||||
def __init__(self, content='', mimetype=None, status=None,
|
||||
content_type=None, request=None):
|
||||
content_type=None, request=None):
|
||||
from django.conf import settings
|
||||
accept_charset = None
|
||||
if mimetype:
|
||||
@ -288,16 +288,12 @@ class HttpResponse(object):
|
||||
if not content_type:
|
||||
content_type = "%s; charset=%s" % (settings.DEFAULT_CONTENT_TYPE,
|
||||
self._charset)
|
||||
if not isinstance(content, basestring) and hasattr(content, '__iter__'):
|
||||
self._container = content
|
||||
self._is_string = False
|
||||
else:
|
||||
self._container = [content]
|
||||
self._is_string = True
|
||||
self._container = [''.join(content)]
|
||||
if hasattr(content, 'close'):
|
||||
content.close()
|
||||
self.cookies = SimpleCookie()
|
||||
if status:
|
||||
self.status_code = status
|
||||
|
||||
# _headers is a mapping of the lower-case name to the original case of
|
||||
# the header (required for working with legacy systems) and the header
|
||||
# value.
|
||||
@ -305,9 +301,8 @@ class HttpResponse(object):
|
||||
|
||||
def __str__(self):
|
||||
"""Full HTTP message, including headers."""
|
||||
return '\n'.join(['%s: %s' % (key, value)
|
||||
for key, value in self._headers.values()]) \
|
||||
+ '\n\n' + self.content
|
||||
headers = ['%s: %s' % (k, v) for k, v in self._headers.values()]
|
||||
return '\n'.join(headers) + '\n\n' + self.content
|
||||
|
||||
def _convert_to_ascii(self, *values):
|
||||
"""Converts all values to ascii strings."""
|
||||
@ -402,8 +397,7 @@ class HttpResponse(object):
|
||||
return smart_str(''.join(self._container), self._codec.name)
|
||||
|
||||
def _set_content(self, value):
|
||||
self._container = [value]
|
||||
self._is_string = True
|
||||
self._container = [''.join(value)]
|
||||
|
||||
content = property(_get_content, _set_content)
|
||||
|
||||
@ -420,22 +414,18 @@ class HttpResponse(object):
|
||||
return str(chunk)
|
||||
|
||||
def close(self):
|
||||
if hasattr(self._container, 'close'):
|
||||
self._container.close()
|
||||
"No-op that remains for backwards compatibility. Ref #6527"
|
||||
pass
|
||||
|
||||
# The remaining methods partially implement the file-like object interface.
|
||||
# See http://docs.python.org/lib/bltin-file-objects.html
|
||||
def write(self, content):
|
||||
if not self._is_string:
|
||||
raise Exception("This %s instance is not writable" % self.__class__)
|
||||
self._container.append(content)
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
def tell(self):
|
||||
if not self._is_string:
|
||||
raise Exception("This %s instance cannot tell its position" % self.__class__)
|
||||
return sum([len(chunk) for chunk in self._container])
|
||||
|
||||
class HttpResponseSendFile(HttpResponse):
|
||||
|
@ -430,12 +430,10 @@ Passing iterators
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Finally, you can pass ``HttpResponse`` an iterator rather than passing it
|
||||
hard-coded strings. If you use this technique, follow these guidelines:
|
||||
hard-coded strings. If you use this technique, note the following:
|
||||
|
||||
* The iterator should return strings.
|
||||
* If an :class:`HttpResponse` has been initialized with an iterator as its
|
||||
content, you can't use the class:`HttpResponse` instance as a file-like
|
||||
object. Doing so will raise ``Exception``.
|
||||
* ``HttpResponse.__init__()`` will read and store the iterator's contents.
|
||||
|
||||
Setting headers
|
||||
~~~~~~~~~~~~~~~
|
||||
|
1
tests/regressiontests/httpwrappers/helloworld.txt
Normal file
1
tests/regressiontests/httpwrappers/helloworld.txt
Normal file
@ -0,0 +1 @@
|
||||
Hello world.
|
@ -463,6 +463,45 @@ BadHeaderError: Header values can't contain newlines (got 'test\\nstr')
|
||||
>>> x.update(y)
|
||||
>>> x.getlist('a')
|
||||
[u'1', u'2', u'3', u'4']
|
||||
|
||||
######################################
|
||||
# HttpResponse with iterable content #
|
||||
######################################
|
||||
|
||||
>>> from django.http import HttpResponse
|
||||
>>> response = HttpResponse(file('regressiontests/httpwrappers/helloworld.txt','r'))
|
||||
>>> print response
|
||||
Content-Type: text/html; charset=utf-8
|
||||
<BLANKLINE>
|
||||
Hello world.
|
||||
<BLANKLINE>
|
||||
|
||||
>>> print response
|
||||
Content-Type: text/html; charset=utf-8
|
||||
<BLANKLINE>
|
||||
Hello world.
|
||||
<BLANKLINE>
|
||||
|
||||
>>> print response
|
||||
Content-Type: text/html; charset=utf-8
|
||||
<BLANKLINE>
|
||||
Hello world.
|
||||
<BLANKLINE>
|
||||
|
||||
>>> response = HttpResponse("abc")
|
||||
>>> print response
|
||||
Content-Type: text/html; charset=utf-8
|
||||
<BLANKLINE>
|
||||
abc
|
||||
>>> print response
|
||||
Content-Type: text/html; charset=utf-8
|
||||
<BLANKLINE>
|
||||
abc
|
||||
>>> print response
|
||||
Content-Type: text/html; charset=utf-8
|
||||
<BLANKLINE>
|
||||
abc
|
||||
|
||||
"""
|
||||
|
||||
from django.http import QueryDict, HttpResponse
|
||||
|
Loading…
x
Reference in New Issue
Block a user