Kaydet (Commit) 82b3e6ff authored tarafından Aymeric Augustin's avatar Aymeric Augustin

Fixed #13222 -- Made HttpResponse iterable once

response.content can be accessed many times as desired, and always
returns the same result.

iter(response) works only once and consumes the iterator.
üst 495a8b81
......@@ -283,7 +283,8 @@ class HttpResponse(HttpResponseBase):
'deprecated. Use `StreamingHttpResponse` instead '
'if you need the streaming behavior.',
PendingDeprecationWarning, stacklevel=2)
self._iterator = iter(self._container)
if not hasattr(self, '_iterator'):
self._iterator = iter(self._container)
return self
def __next__(self):
......@@ -303,7 +304,7 @@ class HttpResponse(HttpResponseBase):
def tell(self):
self._consume_content()
return sum(len(chunk) for chunk in self)
return len(self.content)
class StreamingHttpResponse(HttpResponseBase):
......
......@@ -596,7 +596,11 @@ class TransactionTestCase(SimpleTestCase):
msg_prefix + "Couldn't retrieve content: Response code was %d"
" (expected %d)" % (response.status_code, status_code))
text = force_text(text, encoding=response._charset)
content = b''.join(response).decode(response._charset)
if response.streaming:
content = b''.join(response.streaming_content)
else:
content = response.content
content = content.decode(response._charset)
# Avoid ResourceWarning about unclosed files.
response.close()
if html:
......
......@@ -337,15 +337,36 @@ class HttpResponseTests(unittest.TestCase):
self.assertRaises(UnicodeEncodeError,
getattr, r, 'content')
# content can safely be accessed multiple times.
# .content can safely be accessed multiple times.
r = HttpResponse(iter(['hello', 'world']))
self.assertEqual(r.content, r.content)
self.assertEqual(r.content, b'helloworld')
# accessing the iterator works (once) after accessing .content
self.assertEqual(b''.join(r), b'helloworld')
self.assertEqual(b''.join(r), b'')
# accessing .content still works
self.assertEqual(r.content, b'helloworld')
# XXX accessing .content doesn't work if the response was iterated first
# XXX change this when the deprecation completes in HttpResponse
r = HttpResponse(iter(['hello', 'world']))
with warnings.catch_warnings():
warnings.simplefilter("ignore", PendingDeprecationWarning)
self.assertEqual(b''.join(r), b'helloworld')
self.assertEqual(r.content, b'') # not the expected result!
# additional content can be written to the response.
r = HttpResponse(iter(['hello', 'world']))
self.assertEqual(r.content, b'helloworld')
r.write('!')
self.assertEqual(r.content, b'helloworld!')
def test_iterator_isnt_rewound(self):
# Regression test for #13222
r = HttpResponse('abc')
i = iter(r)
self.assertEqual(list(i), [b'abc'])
self.assertEqual(list(i), [])
def test_file_interface(self):
r = HttpResponse()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment