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:
parent
dc39762fde
commit
c3d7aad6d0
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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):
|
||||||
|
|
Loading…
Reference in New Issue