fix: proxy=None no longer drops an explicit proxies= (IP unmask); cookie views work off-loop
request(proxy=None, proxies={...}) silently sent direct because setdefault('proxy', ...)
is a no-op when the None key already exists, unmasking the caller's real IP - now a bare
proxy=None is replaced by the resolved proxies= (the both-set guard still rejects two real
proxies). get_cookies/clear_cookies return {}/no-op when no session was built yet (mirroring
preview) instead of forcing a build that needs a running loop; set_cookie, which genuinely
needs the jar, now raises a clear actionable error off-loop instead of aiohttp's opaque one.
Signed-off-by: disqualifier <dev@disqualifier.me>
This commit is contained in:
+25
-3
@@ -245,7 +245,11 @@ class ExtendedSession:
|
||||
|
||||
iterates the jar directly rather than filter_cookies() (which needs a url and,
|
||||
given none, returns only domain-less shared cookies - {} for any normal one).
|
||||
returns {} off-loop when no session was built yet (nothing could be set), mirroring
|
||||
preview() - reaching self.session would build it and need a running loop.
|
||||
"""
|
||||
if self._session is None:
|
||||
return {}
|
||||
return {c.key: c.value for c in self.session.cookie_jar}
|
||||
|
||||
def set_cookie(self, name, value, domain=None, path="/"):
|
||||
@@ -262,6 +266,15 @@ class ExtendedSession:
|
||||
to IP hosts with no store, no send, and no log - construct the session
|
||||
with cookie_jar=aiohttp.CookieJar(unsafe=True) to allow IP-host cookies
|
||||
"""
|
||||
if self._session is None:
|
||||
try:
|
||||
self._ensure_session()
|
||||
except RuntimeError as error:
|
||||
raise RuntimeError(
|
||||
"set_cookie needs the backend cookie jar, which builds on first use and "
|
||||
"requires a running event loop; call it inside an async context (unlike "
|
||||
"get_cookies/clear_cookies, which no-op off-loop)"
|
||||
) from error
|
||||
cookie = SimpleCookie()
|
||||
cookie[name] = value
|
||||
cookie[name]["path"] = path
|
||||
@@ -283,7 +296,13 @@ class ExtendedSession:
|
||||
jar.update_cookies(cookie, response_url=url)
|
||||
|
||||
def clear_cookies(self):
|
||||
"""clear the session cookie jar"""
|
||||
"""clear the session cookie jar
|
||||
|
||||
a no-op off-loop when no session was built yet (an unbuilt jar is already empty),
|
||||
so callers can clear before the loop starts without a spurious session build.
|
||||
"""
|
||||
if self._session is None:
|
||||
return
|
||||
self.session.cookie_jar.clear()
|
||||
|
||||
def _cookies_for_url(self, url):
|
||||
@@ -366,9 +385,12 @@ class ExtendedSession:
|
||||
unmask the caller's real IP) - pass only one of them.
|
||||
"""
|
||||
resolved_proxy = self._get_proxy(url, kwargs.pop("proxies", None))
|
||||
if "proxy" in kwargs and kwargs["proxy"] is not None and resolved_proxy is not None:
|
||||
if kwargs.get("proxy") is not None and resolved_proxy is not None:
|
||||
raise ValueError("pass only one of proxy= or proxies= (session/per-call), not both")
|
||||
kwargs.setdefault("proxy", resolved_proxy)
|
||||
# a bare proxy=None must not shadow a resolved proxies= (that would send direct and
|
||||
# unmask the caller's IP); setdefault can't fix it because the None key already exists
|
||||
if kwargs.get("proxy") is None:
|
||||
kwargs["proxy"] = resolved_proxy
|
||||
debug = kwargs.pop("debug", False)
|
||||
|
||||
merged = {**self._default_headers, **(kwargs.get("headers") or {})}
|
||||
|
||||
Reference in New Issue
Block a user