From fdf932c61c7ff77d494a4a413cc5fbdb71328ac7 Mon Sep 17 00:00:00 2001 From: Tim Konick Date: Mon, 22 Sep 2014 12:04:29 -0400 Subject: [PATCH 1/5] raise RuntimeError when a single streamed request calls *iter methods than once --- requests/models.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/requests/models.py b/requests/models.py index bbf08c81..a6af6427 100644 --- a/requests/models.py +++ b/requests/models.py @@ -655,8 +655,12 @@ class Response(object): self._content_consumed = True - # simulate reading small chunks of the content - reused_chunks = iter_slices(self._content, chunk_size) + if self._content_consumed and isinstance(self._content, bool): + raise RuntimeError( + 'The content for this response was already consumed') + else: + # simulate reading small chunks of the content + reused_chunks = iter_slices(self._content, chunk_size) stream_chunks = generate() From d6470870d08828c1d332ae446d5288eaab55d1f1 Mon Sep 17 00:00:00 2001 From: Tim Konick Date: Mon, 22 Sep 2014 12:46:07 -0400 Subject: [PATCH 2/5] rm `else` after `if` then `raise` block --- requests/models.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/requests/models.py b/requests/models.py index a6af6427..5974507b 100644 --- a/requests/models.py +++ b/requests/models.py @@ -658,9 +658,8 @@ class Response(object): if self._content_consumed and isinstance(self._content, bool): raise RuntimeError( 'The content for this response was already consumed') - else: - # simulate reading small chunks of the content - reused_chunks = iter_slices(self._content, chunk_size) + # simulate reading small chunks of the content + reused_chunks = iter_slices(self._content, chunk_size) stream_chunks = generate() From 58e0a6f4a020db660119f1c9459ab37ba55b92d4 Mon Sep 17 00:00:00 2001 From: Tim Konick Date: Mon, 22 Sep 2014 15:51:10 -0400 Subject: [PATCH 3/5] add-in StreamConsumedError --- requests/exceptions.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/requests/exceptions.py b/requests/exceptions.py index d8f05f08..32a18542 100644 --- a/requests/exceptions.py +++ b/requests/exceptions.py @@ -89,3 +89,6 @@ class ChunkedEncodingError(RequestException): class ContentDecodingError(RequestException, BaseHTTPError): """Failed to decode response content""" + +class StreamConsumedError(RequestException): + """The content for this response was already consumed""" From 6e5f7bb9d397ade498ee22d9785863ef1b8ad946 Mon Sep 17 00:00:00 2001 From: Tim Konick Date: Mon, 22 Sep 2014 15:51:59 -0400 Subject: [PATCH 4/5] using the `StreamConsumedError` --- requests/models.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/requests/models.py b/requests/models.py index 5974507b..897cd6fd 100644 --- a/requests/models.py +++ b/requests/models.py @@ -22,8 +22,9 @@ from .packages.urllib3.util import parse_url from .packages.urllib3.exceptions import ( DecodeError, ReadTimeoutError, ProtocolError) from .exceptions import ( - HTTPError, RequestException, MissingSchema, InvalidURL, - ChunkedEncodingError, ContentDecodingError, ConnectionError) + HTTPError, RequestException, MissingSchema, InvalidURL, + ChunkedEncodingError, ContentDecodingError, ConnectionError, + StreamConsumedError) from .utils import ( guess_filename, get_auth_from_url, requote_uri, stream_decode_response_unicode, to_key_val_list, parse_header_links, @@ -656,8 +657,7 @@ class Response(object): self._content_consumed = True if self._content_consumed and isinstance(self._content, bool): - raise RuntimeError( - 'The content for this response was already consumed') + raise StreamConsumedError() # simulate reading small chunks of the content reused_chunks = iter_slices(self._content, chunk_size) From 64ba451049c614eb14d336c2e7989ffaa81b2bb5 Mon Sep 17 00:00:00 2001 From: Tim Konick Date: Mon, 22 Sep 2014 15:58:54 -0400 Subject: [PATCH 5/5] make StreamConsumedError doubly inherit --- requests/exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requests/exceptions.py b/requests/exceptions.py index 32a18542..34c7a0db 100644 --- a/requests/exceptions.py +++ b/requests/exceptions.py @@ -90,5 +90,5 @@ class ChunkedEncodingError(RequestException): class ContentDecodingError(RequestException, BaseHTTPError): """Failed to decode response content""" -class StreamConsumedError(RequestException): +class StreamConsumedError(RequestException, TypeError): """The content for this response was already consumed"""