Skip to content

Commit 6aba616

Browse files
authored
serialize: remove v1 and v2 formats (#310)
* serialize: remove v1 and v2 formats Closes #309. * release_notes: document * serialize: remove old imports and helpers
1 parent 71e071c commit 6aba616

File tree

3 files changed

+22
-76
lines changed

3 files changed

+22
-76
lines changed

cachecontrol/serialize.py

Lines changed: 9 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@
22
#
33
# SPDX-License-Identifier: Apache-2.0
44

5-
import base64
65
import io
7-
import json
8-
import pickle
9-
import zlib
106
from typing import IO, TYPE_CHECKING, Any, Mapping, Optional
117

128
import msgpack
@@ -17,17 +13,6 @@
1713
from requests import PreparedRequest, Request
1814

1915

20-
def _b64_decode_bytes(b: str) -> bytes:
21-
return base64.b64decode(b.encode("ascii"))
22-
23-
24-
def _b64_decode_str(s: str) -> str:
25-
return _b64_decode_bytes(s).decode("utf8")
26-
27-
28-
_default_body_read = object()
29-
30-
3116
class Serializer(object):
3217
def dumps(
3318
self,
@@ -167,46 +152,28 @@ def _loads_v0(
167152
# The original legacy cache data. This doesn't contain enough
168153
# information to construct everything we need, so we'll treat this as
169154
# a miss.
170-
return
155+
return None
171156

172157
def _loads_v1(
173158
self,
174159
request: "Request",
175160
data: bytes,
176161
body_file: Optional["IO[bytes]"] = None,
177162
) -> Optional[HTTPResponse]:
178-
try:
179-
cached = pickle.loads(data)
180-
except ValueError:
181-
return None
182-
183-
return self.prepare_response(request, cached, body_file)
163+
# The "v1" pickled cache format. This is no longer supported
164+
# for security reasons, so we treat it as a miss.
165+
return None
184166

185167
def _loads_v2(
186168
self,
187169
request: "Request",
188170
data: bytes,
189171
body_file: Optional["IO[bytes]"] = None,
190172
) -> Optional[HTTPResponse]:
191-
assert body_file is None
192-
try:
193-
cached = json.loads(zlib.decompress(data).decode("utf8"))
194-
except (ValueError, zlib.error):
195-
return None
196-
197-
# We need to decode the items that we've base64 encoded
198-
cached["response"]["body"] = _b64_decode_bytes(cached["response"]["body"])
199-
cached["response"]["headers"] = dict(
200-
(_b64_decode_str(k), _b64_decode_str(v))
201-
for k, v in cached["response"]["headers"].items()
202-
)
203-
cached["response"]["reason"] = _b64_decode_str(cached["response"]["reason"])
204-
cached["vary"] = dict(
205-
(_b64_decode_str(k), _b64_decode_str(v) if v is not None else v)
206-
for k, v in cached["vary"].items()
207-
)
208-
209-
return self.prepare_response(request, cached, body_file)
173+
# The "v2" compressed base64 cache format.
174+
# This has been removed due to age and poor size/performance
175+
# characteristics, so we treat it as a miss.
176+
return None
210177

211178
def _loads_v3(
212179
self,
@@ -217,7 +184,7 @@ def _loads_v3(
217184
# Due to Python 2 encoding issues, it's impossible to know for sure
218185
# exactly how to load v3 entries, thus we'll treat these as a miss so
219186
# that they get rewritten out as v4 entries.
220-
return
187+
return None
221188

222189
def _loads_v4(
223190
self,

docs/release_notes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
Release Notes
88
===============
99

10+
Unreleased
11+
==========
12+
13+
* Support for old serialization formats has been removed.
14+
1015
0.13.0
1116
======
1217

tests/test_serialization.py

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,17 @@ def test_load_by_version_v0(self):
3838
resp = self.serializer.loads(req, data)
3939
assert resp is None
4040

41-
def test_read_version_v1(self):
41+
def test_load_by_version_v1(self):
42+
data = b"cc=1,somedata"
4243
req = Mock()
43-
resp = self.serializer._loads_v1(req, pickle.dumps(self.response_data))
44-
# We have to decode our urllib3 data back into a unicode string.
45-
assert resp.data == "Hello World".encode("utf-8")
44+
resp = self.serializer.loads(req, data)
45+
assert resp is None
4646

47-
def test_read_version_v2(self):
47+
def test_load_by_version_v2(self):
48+
data = b"cc=2,somedata"
4849
req = Mock()
49-
compressed_base64_json = b"x\x9c%O\xb9\n\x83@\x10\xfd\x97\xa9-\x92%E\x14R\xe4 +\x16\t\xe6\x10\xbb\xb0\xc7\xe0\x81\xb8\xb2\xbb*A\xfc\xf7\x8c\xa6|\xe7\xbc\x99\xc0\xa2\xebL\xeb\x10\xa2\t\xa4\xd1_\x88\xe0\xc93'\xf9\xbe\xc8X\xf8\x95<=@\x00\x1a\x95\xd1\xf8Q\xa6\xf5\xd8z\x88\xbc\xed1\x80\x12\x85F\xeb\x96h\xca\xc2^\xf3\xac\xd7\xe7\xed\x1b\xf3SC5\x04w\xfa\x1c\x8e\x92_;Y\x1c\x96\x9a\x94]k\xc1\xdf~u\xc7\xc9 \x8fDG\xa0\xe2\xac\x92\xbc\xa9\xc9\xf1\xc8\xcbQ\xe4I\xa3\xc6U\xb9_\x14\xbb\xbdh\xc2\x1c\xd0R\xe1LK$\xd9\x9c\x17\xbe\xa7\xc3l\xb3Y\x80\xad\x94\xff\x0b\x03\xed\xa9V\x17[2\x83\xb0\xf4\xd14\xcf?E\x03Im"
50-
resp = self.serializer._loads_v2(req, compressed_base64_json)
51-
# We have to decode our urllib3 data back into a unicode string.
52-
assert resp.data == "Hello World".encode("utf-8")
50+
resp = self.serializer.loads(req, data)
51+
assert resp is None
5352

5453
def test_load_by_version_v3(self):
5554
data = b"cc=3,somedata"
@@ -63,31 +62,6 @@ def test_read_version_v4(self):
6362
# We have to decode our urllib3 data back into a unicode string.
6463
assert resp.data == "Hello World".encode("utf-8")
6564

66-
def test_read_v1_serialized_with_py2_TypeError(self):
67-
# This tests how the code handles in reading data that was pickled
68-
# with an old version of cachecontrol running under Python 2
69-
req = Mock()
70-
py2_pickled_data = b"".join(
71-
[
72-
b"(dp1\nS'response'\np2\n(dp3\nS'body'\np4\nS'Hello World'\n",
73-
b"p5\nsS'version'\np6\nS'2'\nsS'status'\np7\nI200\n",
74-
b"sS'reason'\np8\nS''\nsS'decode_content'\np9\nI01\n",
75-
b"sS'strict'\np10\nS''\nsS'headers'\np11\n(dp12\n",
76-
b"S'Content-Type'\np13\nS'text/plain'\np14\n",
77-
b"sS'Cache-Control'\np15\nS'public'\np16\n",
78-
b"sS'Expires'\np17\nS'87654'\np18\nsss.",
79-
]
80-
)
81-
resp = self.serializer._loads_v1(req, py2_pickled_data)
82-
# We have to decode our urllib3 data back into a unicode
83-
# string.
84-
assert resp.data == "Hello World".encode("utf-8")
85-
86-
def test_read_v2_corrupted_cache(self):
87-
# This should prevent a regression of bug #134
88-
req = Mock()
89-
assert self.serializer._loads_v2(req, b"") is None
90-
9165
def test_read_latest_version_streamable(self, url):
9266
original_resp = requests.get(url, stream=True)
9367
req = original_resp.request

0 commit comments

Comments
 (0)