From f502cc32ecd75b069150ede44a12b4fb6689aafb Mon Sep 17 00:00:00 2001 From: Cycloctane Date: Wed, 18 Dec 2024 02:26:51 +0800 Subject: [PATCH] Use `quote_cookie` setting from ClientSession's cookiejar in `tmp_cookie_jar` (#10093) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Sam Bull (cherry picked from commit 7b5d54a96c1dd1282e9a79f9fc8056c02ca91c6f) --- CHANGES/10093.bugfix.rst | 2 ++ aiohttp/abc.py | 5 +++++ aiohttp/client.py | 4 +++- aiohttp/cookiejar.py | 8 ++++++++ tests/test_client_session.py | 23 ++++++++++++++++++++--- tests/test_cookiejar.py | 1 + 6 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 CHANGES/10093.bugfix.rst diff --git a/CHANGES/10093.bugfix.rst b/CHANGES/10093.bugfix.rst new file mode 100644 index 00000000000..4d7076115d9 --- /dev/null +++ b/CHANGES/10093.bugfix.rst @@ -0,0 +1,2 @@ +Update :py:meth:`~aiohttp.ClientSession.request` to reuse the ``quote_cookie`` setting from ``ClientSession._cookie_jar`` when processing cookies parameter. +-- by :user:`Cycloctane`. diff --git a/aiohttp/abc.py b/aiohttp/abc.py index 989f0a561ff..5794a9108b0 100644 --- a/aiohttp/abc.py +++ b/aiohttp/abc.py @@ -176,6 +176,11 @@ class AbstractCookieJar(Sized, IterableBase): def __init__(self, *, loop: Optional[asyncio.AbstractEventLoop] = None) -> None: self._loop = loop or asyncio.get_running_loop() + @property + @abstractmethod + def quote_cookie(self) -> bool: + """Return True if cookies should be quoted.""" + @abstractmethod def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None: """Clear all cookies if no predicate is passed.""" diff --git a/aiohttp/client.py b/aiohttp/client.py index 7539310aa8a..fbf691e89d1 100644 --- a/aiohttp/client.py +++ b/aiohttp/client.py @@ -656,7 +656,9 @@ async def _request( all_cookies = self._cookie_jar.filter_cookies(url) if cookies is not None: - tmp_cookie_jar = CookieJar() + tmp_cookie_jar = CookieJar( + quote_cookie=self._cookie_jar.quote_cookie + ) tmp_cookie_jar.update_cookies(cookies) req_cookies = tmp_cookie_jar.filter_cookies(url) if req_cookies: diff --git a/aiohttp/cookiejar.py b/aiohttp/cookiejar.py index ef04bda5ad6..f6b9a921767 100644 --- a/aiohttp/cookiejar.py +++ b/aiohttp/cookiejar.py @@ -117,6 +117,10 @@ def __init__( self._expire_heap: List[Tuple[float, Tuple[str, str, str]]] = [] self._expirations: Dict[Tuple[str, str, str], float] = {} + @property + def quote_cookie(self) -> bool: + return self._quote_cookie + def save(self, file_path: PathLike) -> None: file_path = pathlib.Path(file_path) with file_path.open(mode="wb") as f: @@ -474,6 +478,10 @@ def __iter__(self) -> "Iterator[Morsel[str]]": def __len__(self) -> int: return 0 + @property + def quote_cookie(self) -> bool: + return True + def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None: pass diff --git a/tests/test_client_session.py b/tests/test_client_session.py index a2c4833b83e..548af5db551 100644 --- a/tests/test_client_session.py +++ b/tests/test_client_session.py @@ -15,13 +15,14 @@ from yarl import URL import aiohttp -from aiohttp import client, hdrs, web +from aiohttp import CookieJar, client, hdrs, web from aiohttp.client import ClientSession from aiohttp.client_proto import ResponseHandler from aiohttp.client_reqrep import ClientRequest from aiohttp.connector import BaseConnector, Connection, TCPConnector, UnixConnector from aiohttp.helpers import DEBUG from aiohttp.http import RawResponseMessage +from aiohttp.pytest_plugin import AiohttpServer from aiohttp.test_utils import make_mocked_coro from aiohttp.tracing import Trace @@ -634,8 +635,24 @@ async def handler(request): assert resp_cookies["response"].value == "resp_value" -async def test_session_default_version(loop) -> None: - session = aiohttp.ClientSession(loop=loop) +async def test_cookies_with_not_quoted_cookie_jar( + aiohttp_server: AiohttpServer, +) -> None: + async def handler(_: web.Request) -> web.Response: + return web.Response() + + app = web.Application() + app.router.add_route("GET", "/", handler) + server = await aiohttp_server(app) + jar = CookieJar(quote_cookie=False) + cookies = {"name": "val=foobar"} + async with aiohttp.ClientSession(cookie_jar=jar) as sess: + resp = await sess.request("GET", server.make_url("/"), cookies=cookies) + assert resp.request_info.headers.get("Cookie", "") == "name=val=foobar" + + +async def test_session_default_version(loop: asyncio.AbstractEventLoop) -> None: + session = aiohttp.ClientSession() assert session.version == aiohttp.HttpVersion11 await session.close() diff --git a/tests/test_cookiejar.py b/tests/test_cookiejar.py index bdcf54fa796..0b440bc2ca6 100644 --- a/tests/test_cookiejar.py +++ b/tests/test_cookiejar.py @@ -807,6 +807,7 @@ async def make_jar(): async def test_dummy_cookie_jar() -> None: cookie = SimpleCookie("foo=bar; Domain=example.com;") dummy_jar = DummyCookieJar() + assert dummy_jar.quote_cookie is True assert len(dummy_jar) == 0 dummy_jar.update_cookies(cookie) assert len(dummy_jar) == 0