Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement filter_cookies() with domain-matching and path-matching #7944

Merged
merged 31 commits into from
Jan 21, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e91ec9d
#7583
xiangxli Dec 4, 2023
d901fcf
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 4, 2023
4bbf230
Update aiohttp/cookiejar.py
xiangxli Dec 4, 2023
9a8a869
Update aiohttp/cookiejar.py
xiangxli Dec 4, 2023
93250eb
Update aiohttp/cookiejar.py
xiangxli Dec 4, 2023
26deaee
remove print
xiangxli Dec 4, 2023
48f4efc
modify to suggetions
xiangxli Dec 4, 2023
5305795
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 4, 2023
4fcbd08
modify tests to suggestions
xiangxli Dec 4, 2023
b176af3
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 4, 2023
02b6baa
Update aiohttp/cookiejar.py
xiangxli Dec 4, 2023
c7a0d3a
modify tests to suggestions
xiangxli Dec 4, 2023
72c88db
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 4, 2023
80c83e4
Update tests/test_cookiejar.py
xiangxli Dec 4, 2023
f6b4d48
modify cookiejar to handle no-path-cookie
xiangxli Dec 4, 2023
9841d19
Nitpicks
Dreamsorcerer Dec 4, 2023
1d5c615
Update aiohttp/cookiejar.py
bdraco Dec 19, 2023
736d768
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 19, 2023
c7ae0e1
Update test_cookiejar.py
Dreamsorcerer Jan 20, 2024
95e0240
Update 7583.feature
Dreamsorcerer Jan 20, 2024
9ff4082
Update tests/test_cookiejar.py
Dreamsorcerer Jan 20, 2024
6adae74
Update CHANGES/7583.feature
Dreamsorcerer Jan 20, 2024
84b772e
Optimise by handling IP outside of loop
Dreamsorcerer Jan 20, 2024
5b56087
Also move shared cookie out of loop
Dreamsorcerer Jan 20, 2024
ded0338
Merge branch 'master' into master
Dreamsorcerer Jan 20, 2024
cd820e8
Update test for coverage
Dreamsorcerer Jan 20, 2024
8ec5db3
Remove now redundant check
Dreamsorcerer Jan 20, 2024
2f6f730
Replace redundant path match
Dreamsorcerer Jan 20, 2024
1cfcd44
Update cookiejar.py
Dreamsorcerer Jan 20, 2024
8557e39
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 20, 2024
ac55d64
Update test_cookiejar.py
Dreamsorcerer Jan 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES/7583.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Implement filter_cookies() with domain-matching and path-matching on the keys, instead of testing every single cookie.
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ William Grzybowski
William S.
Wilson Ong
wouter bolsterlee
Xiang Li
Yang Zhou
Yannick Koechlin
Yannick Péroux
Expand Down
29 changes: 27 additions & 2 deletions aiohttp/cookiejar.py
Dreamsorcerer marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import calendar
import contextlib
import datetime
import itertools
import os # noqa
import pathlib
import pickle
Expand Down Expand Up @@ -78,7 +79,7 @@ def __init__(
*,
unsafe: bool = False,
quote_cookie: bool = True,
treat_as_secure_origin: Union[StrOrURL, List[StrOrURL], None] = None
treat_as_secure_origin: Union[StrOrURL, List[StrOrURL], None] = None,
) -> None:
self._cookies: DefaultDict[Tuple[str, str], SimpleCookie] = defaultdict(
SimpleCookie
Expand Down Expand Up @@ -261,8 +262,32 @@ def filter_cookies(self, request_url: URL = URL()) -> "BaseCookie[str]":
request_origin = request_url.origin()
is_not_secure = request_origin not in self._treat_as_secure_origin

# d: domain, d could be subdomain
# p: path
d = hostname

pairs = []
while d:
p = request_url.path
bdraco marked this conversation as resolved.
Show resolved Hide resolved
while p:
pairs.append((d, p))
p = p.rsplit("/", maxsplit=1)[0]
bdraco marked this conversation as resolved.
Show resolved Hide resolved

try:
d = d.split(".", maxsplit=1)[1]
bdraco marked this conversation as resolved.
Show resolved Hide resolved
except IndexError:
# handle last element for split
d = ""

# shared cookie, it should have max of 1 entry
pairs.append(("", "/"))

cookies = itertools.chain.from_iterable(
self._cookies[p].values() for p in reversed(pairs)
)

# Point 2: https://www.rfc-editor.org/rfc/rfc6265.html#section-5.4
for cookie in sorted(self, key=lambda c: len(c["path"])):
for cookie in cookies:
name = cookie.key
domain = cookie["domain"]

Expand Down
72 changes: 72 additions & 0 deletions tests/test_cookiejar.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,78 @@ async def test_filter_cookies_str_deprecated(loop: Any) -> None:
jar.filter_cookies("http://éé.com")


@pytest.mark.parametrize(
("url", "expected_cookies"),
[
(
"http://pathtest.com/one/two/",
[
"path2-cookie",
"shared-cookie",
"path3-cookie",
"path4-cookie",
Dreamsorcerer marked this conversation as resolved.
Show resolved Hide resolved
],
),
(
"http://test1.example.com/",
[
"shared-cookie",
"domain-cookie",
"subdomain1-cookie",
"dotted-domain-cookie",
],
),
(
"http://pathtest.com/",
[
"shared-cookie",
"no-path-cookie",
"path1-cookie",
],
),
],
ids=(
"/one/two/ path",
"test1.example.com subdomain",
"pathtest.com",
),
xiangxli marked this conversation as resolved.
Show resolved Hide resolved
)
async def test_filter_cookies_with_domain_path_lookup_multilevelpath(
loop: Any,
url: Any,
expected_cookies: Any,
) -> None:
jar = CookieJar()
cookies = SimpleCookie(
"shared-cookie=first; "
"domain-cookie=second; Domain=example.com; "
"subdomain1-cookie=third; Domain=test1.example.com; "
"subdomain2-cookie=fourth; Domain=test2.example.com; "
"dotted-domain-cookie=fifth; Domain=.example.com; "
"different-domain-cookie=sixth; Domain=different.org; "
"secure-cookie=seventh; Domain=secure.com; Secure; "
"no-path-cookie=eighth; Domain=pathtest.com; "
"path1-cookie=ninth; Domain=pathtest.com; Path=/; "
"path2-cookie=tenth; Domain=pathtest.com; Path=/one; "
"path3-cookie=eleventh; Domain=pathtest.com; Path=/one/two; "
"path4-cookie=twelfth; Domain=pathtest.com; Path=/one/two/; "
"expires-cookie=thirteenth; Domain=expirestest.com; Path=/;"
" Expires=Tue, 1 Jan 1980 12:00:00 GMT; "
"max-age-cookie=fourteenth; Domain=maxagetest.com; Path=/;"
" Max-Age=60; "
"invalid-max-age-cookie=fifteenth; Domain=invalid-values.com; "
" Max-Age=string; "
"invalid-expires-cookie=sixteenth; Domain=invalid-values.com; "
" Expires=string;"
)
jar.update_cookies(cookies)
cookies = jar.filter_cookies(URL(url))

assert len(cookies) == len(expected_cookies)
for c in cookies:
assert c in expected_cookies


async def test_domain_filter_ip_cookie_send(loop: Any) -> None:
jar = CookieJar()
cookies = SimpleCookie(
Expand Down
Loading