diff --git a/cachecontrol/serialize.py b/cachecontrol/serialize.py index f0c215c0..44ecc61e 100644 --- a/cachecontrol/serialize.py +++ b/cachecontrol/serialize.py @@ -34,6 +34,7 @@ def dumps(self, request, response, body=None): # sure it acts as though it was never read. body = response.read(decode_content=False) response._fp = io.BytesIO(body) + response.length_remaining = len(body) # NOTE: This is all a bit weird, but it's really important that on # Python 2.x these objects are unicode and not str, even when diff --git a/tests/conftest.py b/tests/conftest.py index 2f1de2da..d363d909 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -104,6 +104,16 @@ def stream(self, env, start_response): for i in range(10): yield pformat(i).encode("utf8") + def fixed_length(self, env, start_response): + body = b"0123456789" + headers = [ + ("Content-Type", "text/plain"), + ("Cache-Control", "max-age=5000"), + ("Content-Length", str(len(body))) + ] + start_response("200 OK", headers) + return [body] + def __call__(self, env, start_response): func = self.dispatch(env) diff --git a/tests/test_serialization.py b/tests/test_serialization.py index 37e3e2fb..af4d18f9 100644 --- a/tests/test_serialization.py +++ b/tests/test_serialization.py @@ -134,3 +134,9 @@ def test_no_body_creates_response_file_handle_on_dumps(self, url): # handle. Reading it again proves we're resetting the internal # file handle with a buffer. assert original_resp.raw.read() + + def test_no_incomplete_read_on_dumps(self, url): + resp = requests.get(url + "fixed_length", stream=True) + self.serializer.dumps(resp.request, resp.raw) + + assert resp.content == b"0123456789"