From 1175a9eeb5c603786aef3f6d20497b561c618a8d Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Mon, 8 May 2023 10:15:22 +0800 Subject: [PATCH] fix: double reading error on urllib3 2.0 Fixes #295 Signed-off-by: Frost Ming --- cachecontrol/serialize.py | 1 + tests/conftest.py | 10 ++++++++++ tests/test_serialization.py | 6 ++++++ 3 files changed, 17 insertions(+) diff --git a/cachecontrol/serialize.py b/cachecontrol/serialize.py index 70135d3..1533104 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 2f1de2d..d363d90 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 4301be4..cab0dca 100644 --- a/tests/test_serialization.py +++ b/tests/test_serialization.py @@ -135,3 +135,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" \ No newline at end of file