Skip to content

Commit 54ceb6f

Browse files
xiangxliDreamsorcererbdraco
authored
Implement filter_cookies() with domain-matching and path-matching (#7944)
--------- Co-authored-by: Sam Bull <[email protected]> Co-authored-by: J. Nick Koston <[email protected]>
1 parent 9e14ea1 commit 54ceb6f

File tree

4 files changed

+141
-60
lines changed

4 files changed

+141
-60
lines changed

CHANGES/7583.feature

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Implement filter_cookies() with domain-matching and path-matching on the keys, instead of testing every single cookie.
2+
This may break existing cookies that have been saved with `CookieJar.save()`. Cookies can be migrated with this script::
3+
4+
import pickle
5+
with file_path.open("rb") as f:
6+
cookies = pickle.load(f)
7+
8+
morsels = [(name, m) for c in cookies.values() for name, m in c.items()]
9+
cookies.clear()
10+
for name, m in morsels:
11+
cookies[(m["domain"], m["path"].rstrip("/"))][name] = m
12+
13+
with file_path.open("wb") as f:
14+
pickle.dump(cookies, f, pickle.HIGHEST_PROTOCOL)

CONTRIBUTORS.txt

+1
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ William Grzybowski
356356
William S.
357357
Wilson Ong
358358
wouter bolsterlee
359+
Xiang Li
359360
Yang Zhou
360361
Yannick Koechlin
361362
Yannick Péroux

aiohttp/cookiejar.py

+31-33
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import calendar
22
import contextlib
33
import datetime
4+
import itertools
45
import os # noqa
56
import pathlib
67
import pickle
@@ -10,7 +11,7 @@
1011
from collections import defaultdict
1112
from http.cookies import BaseCookie, Morsel, SimpleCookie
1213
from math import ceil
13-
from typing import ( # noqa
14+
from typing import (
1415
DefaultDict,
1516
Dict,
1617
Iterable,
@@ -78,7 +79,7 @@ def __init__(
7879
*,
7980
unsafe: bool = False,
8081
quote_cookie: bool = True,
81-
treat_as_secure_origin: Union[StrOrURL, List[StrOrURL], None] = None
82+
treat_as_secure_origin: Union[StrOrURL, List[StrOrURL], None] = None,
8283
) -> None:
8384
self._cookies: DefaultDict[Tuple[str, str], SimpleCookie] = defaultdict(
8485
SimpleCookie
@@ -209,6 +210,7 @@ def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> No
209210
# Cut everything from the last slash to the end
210211
path = "/" + path[1 : path.rfind("/")]
211212
cookie["path"] = path
213+
path = path.rstrip("/")
212214

213215
max_age = cookie["max-age"]
214216
if max_age:
@@ -261,26 +263,41 @@ def filter_cookies(self, request_url: URL = URL()) -> "BaseCookie[str]":
261263
request_origin = request_url.origin()
262264
is_not_secure = request_origin not in self._treat_as_secure_origin
263265

266+
# Send shared cookie
267+
for c in self._cookies[("", "")].values():
268+
filtered[c.key] = c.value
269+
270+
if is_ip_address(hostname):
271+
if not self._unsafe:
272+
return filtered
273+
domains: Iterable[str] = (hostname,)
274+
else:
275+
# Get all the subdomains that might match a cookie (e.g. "foo.bar.com", "bar.com", "com")
276+
domains = itertools.accumulate(
277+
reversed(hostname.split(".")), lambda x, y: f"{y}.{x}"
278+
)
279+
# Get all the path prefixes that might match a cookie (e.g. "", "/foo", "/foo/bar")
280+
paths = itertools.accumulate(
281+
request_url.path.split("/"), lambda x, y: f"{x}/{y}"
282+
)
283+
# Create every combination of (domain, path) pairs.
284+
pairs = itertools.product(domains, paths)
285+
264286
# Point 2: https://www.rfc-editor.org/rfc/rfc6265.html#section-5.4
265-
for cookie in sorted(self, key=lambda c: len(c["path"])):
287+
cookies = itertools.chain.from_iterable(
288+
self._cookies[p].values() for p in pairs
289+
)
290+
path_len = len(request_url.path)
291+
for cookie in cookies:
266292
name = cookie.key
267293
domain = cookie["domain"]
268294

269-
# Send shared cookies
270-
if not domain:
271-
filtered[name] = cookie.value
272-
continue
273-
274-
if not self._unsafe and is_ip_address(hostname):
275-
continue
276-
277295
if (domain, name) in self._host_only_cookies:
278296
if domain != hostname:
279297
continue
280-
elif not self._is_domain_match(domain, hostname):
281-
continue
282298

283-
if not self._is_path_match(request_url.path, cookie["path"]):
299+
# Skip edge case when the cookie has a trailing slash but request doesn't.
300+
if len(cookie["path"]) > path_len:
284301
continue
285302

286303
if is_not_secure and cookie["secure"]:
@@ -310,25 +327,6 @@ def _is_domain_match(domain: str, hostname: str) -> bool:
310327

311328
return not is_ip_address(hostname)
312329

313-
@staticmethod
314-
def _is_path_match(req_path: str, cookie_path: str) -> bool:
315-
"""Implements path matching adhering to RFC 6265."""
316-
if not req_path.startswith("/"):
317-
req_path = "/"
318-
319-
if req_path == cookie_path:
320-
return True
321-
322-
if not req_path.startswith(cookie_path):
323-
return False
324-
325-
if cookie_path.endswith("/"):
326-
return True
327-
328-
non_matching = req_path[len(cookie_path) :]
329-
330-
return non_matching.startswith("/")
331-
332330
@classmethod
333331
def _parse_date(cls, date_str: str) -> Optional[int]:
334332
"""Implements date string parsing adhering to RFC 6265."""

tests/test_cookiejar.py

+95-27
Original file line numberDiff line numberDiff line change
@@ -155,28 +155,6 @@ def test_domain_matching() -> None:
155155
assert not test_func("test.com", "127.0.0.1")
156156

157157

158-
def test_path_matching() -> None:
159-
test_func = CookieJar._is_path_match
160-
161-
assert test_func("/", "")
162-
assert test_func("", "/")
163-
assert test_func("/file", "")
164-
assert test_func("/folder/file", "")
165-
assert test_func("/", "/")
166-
assert test_func("/file", "/")
167-
assert test_func("/file", "/file")
168-
assert test_func("/folder/", "/folder/")
169-
assert test_func("/folder/", "/")
170-
assert test_func("/folder/file", "/")
171-
172-
assert not test_func("/", "/file")
173-
assert not test_func("/", "/folder/")
174-
assert not test_func("/file", "/folder/file")
175-
assert not test_func("/folder/", "/folder/file")
176-
assert not test_func("/different-file", "/file")
177-
assert not test_func("/different-folder/", "/folder/")
178-
179-
180158
async def test_constructor(cookies_to_send: Any, cookies_to_receive: Any) -> None:
181159
jar = CookieJar()
182160
jar.update_cookies(cookies_to_send)
@@ -253,6 +231,96 @@ async def test_filter_cookies_str_deprecated(loop: Any) -> None:
253231
jar.filter_cookies("http://éé.com")
254232

255233

234+
@pytest.mark.parametrize(
235+
("url", "expected_cookies"),
236+
(
237+
(
238+
"http://pathtest.com/one/two/",
239+
(
240+
"no-path-cookie",
241+
"path1-cookie",
242+
"path2-cookie",
243+
"shared-cookie",
244+
"path3-cookie",
245+
"path4-cookie",
246+
),
247+
),
248+
(
249+
"http://pathtest.com/one/two",
250+
(
251+
"no-path-cookie",
252+
"path1-cookie",
253+
"path2-cookie",
254+
"shared-cookie",
255+
"path3-cookie",
256+
),
257+
),
258+
(
259+
"http://pathtest.com/one/two/three/",
260+
(
261+
"no-path-cookie",
262+
"path1-cookie",
263+
"path2-cookie",
264+
"shared-cookie",
265+
"path3-cookie",
266+
"path4-cookie",
267+
),
268+
),
269+
(
270+
"http://test1.example.com/",
271+
(
272+
"shared-cookie",
273+
"domain-cookie",
274+
"subdomain1-cookie",
275+
"dotted-domain-cookie",
276+
),
277+
),
278+
(
279+
"http://pathtest.com/",
280+
(
281+
"shared-cookie",
282+
"no-path-cookie",
283+
"path1-cookie",
284+
),
285+
),
286+
),
287+
)
288+
async def test_filter_cookies_with_domain_path_lookup_multilevelpath(
289+
loop: Any,
290+
url: Any,
291+
expected_cookies: Any,
292+
) -> None:
293+
jar = CookieJar()
294+
cookies = SimpleCookie(
295+
"shared-cookie=first; "
296+
"domain-cookie=second; Domain=example.com; "
297+
"subdomain1-cookie=third; Domain=test1.example.com; "
298+
"subdomain2-cookie=fourth; Domain=test2.example.com; "
299+
"dotted-domain-cookie=fifth; Domain=.example.com; "
300+
"different-domain-cookie=sixth; Domain=different.org; "
301+
"secure-cookie=seventh; Domain=secure.com; Secure; "
302+
"no-path-cookie=eighth; Domain=pathtest.com; "
303+
"path1-cookie=ninth; Domain=pathtest.com; Path=/; "
304+
"path2-cookie=tenth; Domain=pathtest.com; Path=/one; "
305+
"path3-cookie=eleventh; Domain=pathtest.com; Path=/one/two; "
306+
"path4-cookie=twelfth; Domain=pathtest.com; Path=/one/two/; "
307+
"expires-cookie=thirteenth; Domain=expirestest.com; Path=/;"
308+
" Expires=Tue, 1 Jan 1980 12:00:00 GMT; "
309+
"max-age-cookie=fourteenth; Domain=maxagetest.com; Path=/;"
310+
" Max-Age=60; "
311+
"invalid-max-age-cookie=fifteenth; Domain=invalid-values.com; "
312+
" Max-Age=string; "
313+
"invalid-expires-cookie=sixteenth; Domain=invalid-values.com; "
314+
" Expires=string;"
315+
)
316+
jar.update_cookies(cookies)
317+
cookies = jar.filter_cookies(URL(url))
318+
319+
assert len(cookies) == len(expected_cookies)
320+
for c in cookies:
321+
assert c in expected_cookies
322+
323+
256324
async def test_domain_filter_ip_cookie_send(loop: Any) -> None:
257325
jar = CookieJar()
258326
cookies = SimpleCookie(
@@ -503,11 +571,11 @@ def test_domain_filter_diff_host(self) -> None:
503571

504572
def test_domain_filter_host_only(self) -> None:
505573
self.jar.update_cookies(self.cookies_to_receive, URL("http://example.com/"))
574+
sub_cookie = SimpleCookie("subdomain=spam; Path=/;")
575+
self.jar.update_cookies(sub_cookie, URL("http://foo.example.com/"))
506576

507-
cookies_sent = self.jar.filter_cookies(URL("http://example.com/"))
508-
self.assertIn("unconstrained-cookie", set(cookies_sent.keys()))
509-
510-
cookies_sent = self.jar.filter_cookies(URL("http://different.org/"))
577+
cookies_sent = self.jar.filter_cookies(URL("http://foo.example.com/"))
578+
self.assertIn("subdomain", set(cookies_sent.keys()))
511579
self.assertNotIn("unconstrained-cookie", set(cookies_sent.keys()))
512580

513581
def test_secure_filter(self) -> None:
@@ -837,7 +905,7 @@ def test_pickle_format(cookies_to_send) -> None:
837905
with file_path.open("wb") as f:
838906
pickle.dump(cookies, f, pickle.HIGHEST_PROTOCOL)
839907
"""
840-
pickled = b"\x80\x05\x95\xc5\x07\x00\x00\x00\x00\x00\x00\x8c\x0bcollections\x94\x8c\x0bdefaultdict\x94\x93\x94\x8c\x0chttp.cookies\x94\x8c\x0cSimpleCookie\x94\x93\x94\x85\x94R\x94(\x8c\x00\x94\x8c\x01/\x94\x86\x94h\x05)\x81\x94\x8c\rshared-cookie\x94h\x03\x8c\x06Morsel\x94\x93\x94)\x81\x94(\x8c\x07expires\x94h\x08\x8c\x04path\x94h\t\x8c\x07comment\x94h\x08\x8c\x06domain\x94h\x08\x8c\x07max-age\x94h\x08\x8c\x06secure\x94h\x08\x8c\x08httponly\x94h\x08\x8c\x07version\x94h\x08\x8c\x08samesite\x94h\x08u}\x94(\x8c\x03key\x94h\x0c\x8c\x05value\x94\x8c\x05first\x94\x8c\x0bcoded_value\x94h\x1cubs\x8c\x0bexample.com\x94h\t\x86\x94h\x05)\x81\x94(\x8c\rdomain-cookie\x94h\x0e)\x81\x94(h\x10h\x08h\x11h\th\x12h\x08h\x13h\x1eh\x14h\x08h\x15h\x08h\x16h\x08h\x17h\x08h\x18h\x08u}\x94(h\x1ah!h\x1b\x8c\x06second\x94h\x1dh$ub\x8c\x14dotted-domain-cookie\x94h\x0e)\x81\x94(h\x10h\x08h\x11h\th\x12h\x08h\x13\x8c\x0bexample.com\x94h\x14h\x08h\x15h\x08h\x16h\x08h\x17h\x08h\x18h\x08u}\x94(h\x1ah%h\x1b\x8c\x05fifth\x94h\x1dh)ubu\x8c\x11test1.example.com\x94h\t\x86\x94h\x05)\x81\x94\x8c\x11subdomain1-cookie\x94h\x0e)\x81\x94(h\x10h\x08h\x11h\th\x12h\x08h\x13h*h\x14h\x08h\x15h\x08h\x16h\x08h\x17h\x08h\x18h\x08u}\x94(h\x1ah-h\x1b\x8c\x05third\x94h\x1dh0ubs\x8c\x11test2.example.com\x94h\t\x86\x94h\x05)\x81\x94\x8c\x11subdomain2-cookie\x94h\x0e)\x81\x94(h\x10h\x08h\x11h\th\x12h\x08h\x13h1h\x14h\x08h\x15h\x08h\x16h\x08h\x17h\x08h\x18h\x08u}\x94(h\x1ah4h\x1b\x8c\x06fourth\x94h\x1dh7ubs\x8c\rdifferent.org\x94h\t\x86\x94h\x05)\x81\x94\x8c\x17different-domain-cookie\x94h\x0e)\x81\x94(h\x10h\x08h\x11h\th\x12h\x08h\x13h8h\x14h\x08h\x15h\x08h\x16h\x08h\x17h\x08h\x18h\x08u}\x94(h\x1ah;h\x1b\x8c\x05sixth\x94h\x1dh>ubs\x8c\nsecure.com\x94h\t\x86\x94h\x05)\x81\x94\x8c\rsecure-cookie\x94h\x0e)\x81\x94(h\x10h\x08h\x11h\th\x12h\x08h\x13h?h\x14h\x08h\x15\x88h\x16h\x08h\x17h\x08h\x18h\x08u}\x94(h\x1ahBh\x1b\x8c\x07seventh\x94h\x1dhEubs\x8c\x0cpathtest.com\x94h\t\x86\x94h\x05)\x81\x94(\x8c\x0eno-path-cookie\x94h\x0e)\x81\x94(h\x10h\x08h\x11h\th\x12h\x08h\x13hFh\x14h\x08h\x15h\x08h\x16h\x08h\x17h\x08h\x18h\x08u}\x94(h\x1ahIh\x1b\x8c\x06eighth\x94h\x1dhLub\x8c\x0cpath1-cookie\x94h\x0e)\x81\x94(h\x10h\x08h\x11h\th\x12h\x08h\x13\x8c\x0cpathtest.com\x94h\x14h\x08h\x15h\x08h\x16h\x08h\x17h\x08h\x18h\x08u}\x94(h\x1ahMh\x1b\x8c\x05ninth\x94h\x1dhQubu\x8c\x0cpathtest.com\x94\x8c\x04/one\x94\x86\x94h\x05)\x81\x94\x8c\x0cpath2-cookie\x94h\x0e)\x81\x94(h\x10h\x08h\x11hSh\x12h\x08h\x13hRh\x14h\x08h\x15h\x08h\x16h\x08h\x17h\x08h\x18h\x08u}\x94(h\x1ahVh\x1b\x8c\x05tenth\x94h\x1dhYubs\x8c\x0cpathtest.com\x94\x8c\x08/one/two\x94\x86\x94h\x05)\x81\x94\x8c\x0cpath3-cookie\x94h\x0e)\x81\x94(h\x10h\x08h\x11h[h\x12h\x08h\x13hZh\x14h\x08h\x15h\x08h\x16h\x08h\x17h\x08h\x18h\x08u}\x94(h\x1ah^h\x1b\x8c\x08eleventh\x94h\x1dhaubs\x8c\x0cpathtest.com\x94\x8c\t/one/two/\x94\x86\x94h\x05)\x81\x94\x8c\x0cpath4-cookie\x94h\x0e)\x81\x94(h\x10h\x08h\x11hch\x12h\x08h\x13hbh\x14h\x08h\x15h\x08h\x16h\x08h\x17h\x08h\x18h\x08u}\x94(h\x1ahfh\x1b\x8c\x07twelfth\x94h\x1dhiubs\x8c\x0fexpirestest.com\x94h\t\x86\x94h\x05)\x81\x94\x8c\x0eexpires-cookie\x94h\x0e)\x81\x94(h\x10\x8c\x1cTue, 1 Jan 2999 12:00:00 GMT\x94h\x11h\th\x12h\x08h\x13hjh\x14h\x08h\x15h\x08h\x16h\x08h\x17h\x08h\x18h\x08u}\x94(h\x1ahmh\x1b\x8c\nthirteenth\x94h\x1dhqubs\x8c\x0emaxagetest.com\x94h\t\x86\x94h\x05)\x81\x94\x8c\x0emax-age-cookie\x94h\x0e)\x81\x94(h\x10h\x08h\x11h\th\x12h\x08h\x13hrh\x14\x8c\x0260\x94h\x15h\x08h\x16h\x08h\x17h\x08h\x18h\x08u}\x94(h\x1ahuh\x1b\x8c\nfourteenth\x94h\x1dhyubs\x8c\x12invalid-values.com\x94h\t\x86\x94h\x05)\x81\x94(\x8c\x16invalid-max-age-cookie\x94h\x0e)\x81\x94(h\x10h\x08h\x11h\th\x12h\x08h\x13hzh\x14h\x08h\x15h\x08h\x16h\x08h\x17h\x08h\x18h\x08u}\x94(h\x1ah}h\x1b\x8c\tfifteenth\x94h\x1dh\x80ub\x8c\x16invalid-expires-cookie\x94h\x0e)\x81\x94(h\x10h\x08h\x11h\th\x12h\x08h\x13\x8c\x12invalid-values.com\x94h\x14h\x08h\x15h\x08h\x16h\x08h\x17h\x08h\x18h\x08u}\x94(h\x1ah\x81h\x1b\x8c\tsixteenth\x94h\x1dh\x85ubuu."
908+
pickled = b"\x80\x04\x95\xc8\x0b\x00\x00\x00\x00\x00\x00\x8c\x0bcollections\x94\x8c\x0bdefaultdict\x94\x93\x94\x8c\x0chttp.cookies\x94\x8c\x0cSimpleCookie\x94\x93\x94\x85\x94R\x94(\x8c\x00\x94h\x08\x86\x94h\x05)\x81\x94\x8c\rshared-cookie\x94h\x03\x8c\x06Morsel\x94\x93\x94)\x81\x94(\x8c\x07expires\x94h\x08\x8c\x04path\x94\x8c\x01/\x94\x8c\x07comment\x94h\x08\x8c\x06domain\x94h\x08\x8c\x07max-age\x94h\x08\x8c\x06secure\x94h\x08\x8c\x08httponly\x94h\x08\x8c\x07version\x94h\x08\x8c\x08samesite\x94h\x08u}\x94(\x8c\x03key\x94h\x0b\x8c\x05value\x94\x8c\x05first\x94\x8c\x0bcoded_value\x94h\x1cubs\x8c\x0bexample.com\x94h\x08\x86\x94h\x05)\x81\x94(\x8c\rdomain-cookie\x94h\r)\x81\x94(\x8c\x07expires\x94h\x08\x8c\x04path\x94h\x11\x8c\x07comment\x94h\x08\x8c\x06domain\x94h\x1e\x8c\x07max-age\x94h\x08\x8c\x06secure\x94h\x08\x8c\x08httponly\x94h\x08\x8c\x07version\x94h\x08\x8c\x08samesite\x94h\x08u}\x94(h\x1ah!h\x1b\x8c\x06second\x94h\x1dh-ub\x8c\x14dotted-domain-cookie\x94h\r)\x81\x94(\x8c\x07expires\x94h\x08\x8c\x04path\x94h\x11\x8c\x07comment\x94h\x08\x8c\x06domain\x94\x8c\x0bexample.com\x94\x8c\x07max-age\x94h\x08\x8c\x06secure\x94h\x08\x8c\x08httponly\x94h\x08\x8c\x07version\x94h\x08\x8c\x08samesite\x94h\x08u}\x94(h\x1ah.h\x1b\x8c\x05fifth\x94h\x1dh;ubu\x8c\x11test1.example.com\x94h\x08\x86\x94h\x05)\x81\x94\x8c\x11subdomain1-cookie\x94h\r)\x81\x94(\x8c\x07expires\x94h\x08\x8c\x04path\x94h\x11\x8c\x07comment\x94h\x08\x8c\x06domain\x94h<\x8c\x07max-age\x94h\x08\x8c\x06secure\x94h\x08\x8c\x08httponly\x94h\x08\x8c\x07version\x94h\x08\x8c\x08samesite\x94h\x08u}\x94(h\x1ah?h\x1b\x8c\x05third\x94h\x1dhKubs\x8c\x11test2.example.com\x94h\x08\x86\x94h\x05)\x81\x94\x8c\x11subdomain2-cookie\x94h\r)\x81\x94(\x8c\x07expires\x94h\x08\x8c\x04path\x94h\x11\x8c\x07comment\x94h\x08\x8c\x06domain\x94hL\x8c\x07max-age\x94h\x08\x8c\x06secure\x94h\x08\x8c\x08httponly\x94h\x08\x8c\x07version\x94h\x08\x8c\x08samesite\x94h\x08u}\x94(h\x1ahOh\x1b\x8c\x06fourth\x94h\x1dh[ubs\x8c\rdifferent.org\x94h\x08\x86\x94h\x05)\x81\x94\x8c\x17different-domain-cookie\x94h\r)\x81\x94(\x8c\x07expires\x94h\x08\x8c\x04path\x94h\x11\x8c\x07comment\x94h\x08\x8c\x06domain\x94h\\\x8c\x07max-age\x94h\x08\x8c\x06secure\x94h\x08\x8c\x08httponly\x94h\x08\x8c\x07version\x94h\x08\x8c\x08samesite\x94h\x08u}\x94(h\x1ah_h\x1b\x8c\x05sixth\x94h\x1dhkubs\x8c\nsecure.com\x94h\x08\x86\x94h\x05)\x81\x94\x8c\rsecure-cookie\x94h\r)\x81\x94(\x8c\x07expires\x94h\x08\x8c\x04path\x94h\x11\x8c\x07comment\x94h\x08\x8c\x06domain\x94hl\x8c\x07max-age\x94h\x08\x8c\x06secure\x94\x88\x8c\x08httponly\x94h\x08\x8c\x07version\x94h\x08\x8c\x08samesite\x94h\x08u}\x94(h\x1ahoh\x1b\x8c\x07seventh\x94h\x1dh{ubs\x8c\x0cpathtest.com\x94h\x08\x86\x94h\x05)\x81\x94(\x8c\x0eno-path-cookie\x94h\r)\x81\x94(\x8c\x07expires\x94h\x08\x8c\x04path\x94h\x11\x8c\x07comment\x94h\x08\x8c\x06domain\x94h|\x8c\x07max-age\x94h\x08\x8c\x06secure\x94h\x08\x8c\x08httponly\x94h\x08\x8c\x07version\x94h\x08\x8c\x08samesite\x94h\x08u}\x94(h\x1ah\x7fh\x1b\x8c\x06eighth\x94h\x1dh\x8bub\x8c\x0cpath1-cookie\x94h\r)\x81\x94(\x8c\x07expires\x94h\x08\x8c\x04path\x94h\x11\x8c\x07comment\x94h\x08\x8c\x06domain\x94\x8c\x0cpathtest.com\x94\x8c\x07max-age\x94h\x08\x8c\x06secure\x94h\x08\x8c\x08httponly\x94h\x08\x8c\x07version\x94h\x08\x8c\x08samesite\x94h\x08u}\x94(h\x1ah\x8ch\x1b\x8c\x05ninth\x94h\x1dh\x99ubu\x8c\x0cpathtest.com\x94\x8c\x04/one\x94\x86\x94h\x05)\x81\x94\x8c\x0cpath2-cookie\x94h\r)\x81\x94(\x8c\x07expires\x94h\x08\x8c\x04path\x94h\x9b\x8c\x07comment\x94h\x08\x8c\x06domain\x94h\x9a\x8c\x07max-age\x94h\x08\x8c\x06secure\x94h\x08\x8c\x08httponly\x94h\x08\x8c\x07version\x94h\x08\x8c\x08samesite\x94h\x08u}\x94(h\x1ah\x9eh\x1b\x8c\x05tenth\x94h\x1dh\xaaubs\x8c\x0cpathtest.com\x94\x8c\x08/one/two\x94\x86\x94h\x05)\x81\x94(\x8c\x0cpath3-cookie\x94h\r)\x81\x94(\x8c\x07expires\x94h\x08\x8c\x04path\x94h\xac\x8c\x07comment\x94h\x08\x8c\x06domain\x94h\xab\x8c\x07max-age\x94h\x08\x8c\x06secure\x94h\x08\x8c\x08httponly\x94h\x08\x8c\x07version\x94h\x08\x8c\x08samesite\x94h\x08u}\x94(h\x1ah\xafh\x1b\x8c\x08eleventh\x94h\x1dh\xbbub\x8c\x0cpath4-cookie\x94h\r)\x81\x94(\x8c\x07expires\x94h\x08\x8c\x04path\x94\x8c\t/one/two/\x94\x8c\x07comment\x94h\x08\x8c\x06domain\x94\x8c\x0cpathtest.com\x94\x8c\x07max-age\x94h\x08\x8c\x06secure\x94h\x08\x8c\x08httponly\x94h\x08\x8c\x07version\x94h\x08\x8c\x08samesite\x94h\x08u}\x94(h\x1ah\xbch\x1b\x8c\x07twelfth\x94h\x1dh\xcaubu\x8c\x0fexpirestest.com\x94h\x08\x86\x94h\x05)\x81\x94\x8c\x0eexpires-cookie\x94h\r)\x81\x94(\x8c\x07expires\x94\x8c\x1cTue, 1 Jan 2999 12:00:00 GMT\x94\x8c\x04path\x94h\x11\x8c\x07comment\x94h\x08\x8c\x06domain\x94h\xcb\x8c\x07max-age\x94h\x08\x8c\x06secure\x94h\x08\x8c\x08httponly\x94h\x08\x8c\x07version\x94h\x08\x8c\x08samesite\x94h\x08u}\x94(h\x1ah\xceh\x1b\x8c\nthirteenth\x94h\x1dh\xdbubs\x8c\x0emaxagetest.com\x94h\x08\x86\x94h\x05)\x81\x94\x8c\x0emax-age-cookie\x94h\r)\x81\x94(\x8c\x07expires\x94h\x08\x8c\x04path\x94h\x11\x8c\x07comment\x94h\x08\x8c\x06domain\x94h\xdc\x8c\x07max-age\x94\x8c\x0260\x94\x8c\x06secure\x94h\x08\x8c\x08httponly\x94h\x08\x8c\x07version\x94h\x08\x8c\x08samesite\x94h\x08u}\x94(h\x1ah\xdfh\x1b\x8c\nfourteenth\x94h\x1dh\xecubs\x8c\x12invalid-values.com\x94h\x08\x86\x94h\x05)\x81\x94(\x8c\x16invalid-max-age-cookie\x94h\r)\x81\x94(\x8c\x07expires\x94h\x08\x8c\x04path\x94h\x11\x8c\x07comment\x94h\x08\x8c\x06domain\x94h\xed\x8c\x07max-age\x94h\x08\x8c\x06secure\x94h\x08\x8c\x08httponly\x94h\x08\x8c\x07version\x94h\x08\x8c\x08samesite\x94h\x08u}\x94(h\x1ah\xf0h\x1b\x8c\tfifteenth\x94h\x1dh\xfcub\x8c\x16invalid-expires-cookie\x94h\r)\x81\x94(\x8c\x07expires\x94h\x08\x8c\x04path\x94h\x11\x8c\x07comment\x94h\x08\x8c\x06domain\x94\x8c\x12invalid-values.com\x94\x8c\x07max-age\x94h\x08\x8c\x06secure\x94h\x08\x8c\x08httponly\x94h\x08\x8c\x07version\x94h\x08\x8c\x08samesite\x94h\x08u}\x94(h\x1ah\xfdh\x1b\x8c\tsixteenth\x94h\x1dj\n\x01\x00\x00ubuu."
841909
cookies = pickle.loads(pickled)
842910

843911
cj = CookieJar()

0 commit comments

Comments
 (0)