fix: CurlCffi preserves duplicate Set-Cookie and get_cookies survives cross-domain names

CIMultiDict(response.headers) consumed curl_cffi Headers.items(), which comma-joins
duplicate header keys, collapsing multiple Set-Cookie lines into one corrupted value -
now uses multi_items() so duplicates stay separate. get_cookies used dict(cookies.items()),
which raises curl_cffi CookieConflict when the same name exists on two domains - now uses
get_dict() (flattens, no raise). Noble.get_cookies prefers get_dict() where the jar exposes
it (unverified live-gap: the noble extra isn't installed here).

Signed-off-by: disqualifier <dev@disqualifier.me>
This commit is contained in:
2026-07-06 19:28:40 -04:00
parent 8ed97a185f
commit ec1a20a3f6
+17 -5
View File
@@ -179,7 +179,7 @@ class CurlCffi:
content = response.content if response.content is not None else b""
return Response(
status_code=response.status_code,
headers=CIMultiDict(response.headers),
headers=CIMultiDict(response.headers.multi_items()),
content=content,
url=str(response.url),
reason=getattr(response, "reason", None),
@@ -208,8 +208,13 @@ class CurlCffi:
session.cookies.set(name, value, domain=domain or "", path=path)
def get_cookies(self, session) -> dict:
"""all cookies stored in curl_cffi's cookie store"""
return dict(session.cookies.items())
"""all cookies stored in curl_cffi's cookie store
uses get_dict() rather than dict(cookies.items()): items() raises curl_cffi
CookieConflict when the same name exists on two domains, get_dict() flattens
(last value wins) without raising.
"""
return session.cookies.get_dict()
def clear_cookies(self, session) -> None:
"""clear curl_cffi's cookie store"""
@@ -339,8 +344,15 @@ class Noble:
session.cookies.set(name, value, domain=domain or "", path=path)
def get_cookies(self, session) -> dict:
"""all cookies stored in noble_tls's cookie jar"""
return dict(session.cookies.items())
"""all cookies stored in noble_tls's cookie jar
prefers get_dict() when the jar exposes it (flattens cross-domain duplicate
names without raising, like curl_cffi); falls back to items() otherwise
"""
jar = session.cookies
if hasattr(jar, "get_dict"):
return jar.get_dict()
return dict(jar.items())
def clear_cookies(self, session) -> None:
"""clear noble_tls's cookie jar"""