Fixed #2560 -- Add close() support to HttpResponse iterators. Thanks, Ivan

Sagalaev.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@3791 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2006-09-22 12:32:00 +00:00
parent dc39762fde
commit c3d7aad6d0
3 changed files with 24 additions and 16 deletions

View File

@ -155,8 +155,11 @@ def populate_apache_request(http_response, mod_python_req):
for c in http_response.cookies.values(): for c in http_response.cookies.values():
mod_python_req.headers_out.add('Set-Cookie', c.output(header='')) mod_python_req.headers_out.add('Set-Cookie', c.output(header=''))
mod_python_req.status = http_response.status_code mod_python_req.status = http_response.status_code
for chunk in http_response.iterator: try:
mod_python_req.write(chunk) for chunk in http_response:
mod_python_req.write(chunk)
finally:
http_response.close()
def handler(req): def handler(req):
# mod_python hooks into this function. # mod_python hooks into this function.

View File

@ -163,4 +163,4 @@ class WSGIHandler(BaseHandler):
for c in response.cookies.values(): for c in response.cookies.values():
response_headers.append(('Set-Cookie', c.output(header=''))) response_headers.append(('Set-Cookie', c.output(header='')))
start_response(status, response_headers) start_response(status, response_headers)
return response.iterator return response

View File

@ -161,10 +161,10 @@ class HttpResponse(object):
if not mimetype: if not mimetype:
mimetype = "%s; charset=%s" % (settings.DEFAULT_CONTENT_TYPE, settings.DEFAULT_CHARSET) mimetype = "%s; charset=%s" % (settings.DEFAULT_CONTENT_TYPE, settings.DEFAULT_CHARSET)
if hasattr(content, '__iter__'): if hasattr(content, '__iter__'):
self._iterator = content self._container = content
self._is_string = False self._is_string = False
else: else:
self._iterator = [content] self._container = [content]
self._is_string = True self._is_string = True
self.headers = {'Content-Type': mimetype} self.headers = {'Content-Type': mimetype}
self.cookies = SimpleCookie() self.cookies = SimpleCookie()
@ -213,32 +213,37 @@ class HttpResponse(object):
self.cookies[key]['max-age'] = 0 self.cookies[key]['max-age'] = 0
def _get_content(self): def _get_content(self):
content = ''.join(self._iterator) content = ''.join(self._container)
if isinstance(content, unicode): if isinstance(content, unicode):
content = content.encode(self._charset) content = content.encode(self._charset)
return content return content
def _set_content(self, value): def _set_content(self, value):
self._iterator = [value] self._container = [value]
self._is_string = True self._is_string = True
content = property(_get_content, _set_content) content = property(_get_content, _set_content)
def _get_iterator(self): def __iter__(self):
"Output iterator. Converts data into client charset if necessary." self._iterator = self._container.__iter__()
for chunk in self._iterator: return self
if isinstance(chunk, unicode):
chunk = chunk.encode(self._charset)
yield chunk
iterator = property(_get_iterator) def next(self):
chunk = self._iterator.next()
if isinstance(chunk, unicode):
chunk = chunk.encode(self._charset)
return chunk
def close(self):
if hasattr(self._container, 'close'):
self._container.close()
# The remaining methods partially implement the file-like object interface. # The remaining methods partially implement the file-like object interface.
# See http://docs.python.org/lib/bltin-file-objects.html # See http://docs.python.org/lib/bltin-file-objects.html
def write(self, content): def write(self, content):
if not self._is_string: if not self._is_string:
raise Exception, "This %s instance is not writable" % self.__class__ raise Exception, "This %s instance is not writable" % self.__class__
self._iterator.append(content) self._container.append(content)
def flush(self): def flush(self):
pass pass
@ -246,7 +251,7 @@ class HttpResponse(object):
def tell(self): def tell(self):
if not self._is_string: if not self._is_string:
raise Exception, "This %s instance cannot tell its position" % self.__class__ raise Exception, "This %s instance cannot tell its position" % self.__class__
return sum([len(chunk) for chunk in self._iterator]) return sum([len(chunk) for chunk in self._container])
class HttpResponseRedirect(HttpResponse): class HttpResponseRedirect(HttpResponse):
def __init__(self, redirect_to): def __init__(self, redirect_to):