Skip to content

Preserve the cookie policy when copying Cookies - #1314

Closed
Kludex wants to merge 1 commit into
mainfrom
preserve-cookie-policy-on-copy
Closed

Kludex wants to merge 1 commit into
mainfrom
preserve-cookie-policy-on-copy

Conversation

@Kludex

@Kludex Kludex commented Nov 4, 2026 •

Copy link
Copy Markdown
Member

Summary

Cookies(<Cookies>) built a new jar with the default policy, dropping the original one. Since #1284 the client only copies its cookies when per-request cookies= are passed, so on that path a policy like blocked_domains on the client jar was ignored and blocked cookies were sent.

Checklist

  • I understand that this PR may be closed in case there was no previous discussion. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.

AI Disclaimer

This PR was developed with the assistance of either Claude or Codex. I've reviewed and verified the changes.

View guided diff

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-04T09:43:05.135654Z af4d3a7 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@codspeed

codspeed Bot commented Nov 4, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 18 untouched benchmarks
⏩ 7 skipped benchmarks1


Comparing preserve-cookie-policy-on-copy (af4d3a7) with main (ec45c95)

Open in CodSpeed

Footnotes

  1. 7 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/httpx2/httpx2/_models.py">

<violation number="1" location="src/httpx2/httpx2/_models.py:1092">
P2: Sharing this policy object makes concurrent per-request cookie jars race on `DefaultCookiePolicy._now`, because each jar locks independently while mutating the shared policy. A shared `Client` can therefore send an expired cookie or omit a still-valid cookie near an expiry boundary; copy the policy state for each new jar or otherwise serialize policy use.</violation>
</file>

Reply with feedback, questions, or to request a fix.

View guided diff | Re-trigger cubic

self.set(key, value)
elif isinstance(cookies, Cookies):
self.jar = IndexedCookieJar()
self.jar = IndexedCookieJar(policy=cookies.jar._policy) # type: ignore[attr-defined]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Sharing this policy object makes concurrent per-request cookie jars race on DefaultCookiePolicy._now, because each jar locks independently while mutating the shared policy. A shared Client can therefore send an expired cookie or omit a still-valid cookie near an expiry boundary; copy the policy state for each new jar or otherwise serialize policy use.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At src/httpx2/httpx2/_models.py, line 1092:

<comment>Sharing this policy object makes concurrent per-request cookie jars race on `DefaultCookiePolicy._now`, because each jar locks independently while mutating the shared policy. A shared `Client` can therefore send an expired cookie or omit a still-valid cookie near an expiry boundary; copy the policy state for each new jar or otherwise serialize policy use.</comment>

<file context>
@@ -1089,7 +1089,7 @@ def __init__(self, cookies: CookieTypes | None = None) -> None:
                 self.set(key, value)
         elif isinstance(cookies, Cookies):
-            self.jar = IndexedCookieJar()
+            self.jar = IndexedCookieJar(policy=cookies.jar._policy)  # type: ignore[attr-defined]
             for cookie in cookies.jar:
                 self.jar.set_cookie(cookie)
</file context>

@Kludex

Kludex commented Nov 4, 2026

Copy link
Copy Markdown
Member Author

Closing this. Reading the jar policy needs the private CookieJar._policy, and since #1284 the policy is only lost when per-request cookies= are passed, which is already deprecated in request().

A search of public code shows per-request cookies are used (e.g. nonebot2 via stream(), posting via build_request()), but no one combines them with a custom CookiePolicy, and no one has reported this.

@Kludex Kludex closed this Nov 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant