Save and load session cookies in Netscape format#81
Open
oalders wants to merge 1 commit into
Open
Conversation
A cookie with no expiration (a session cookie) was silently dropped by HTTP::Cookies::Netscape: on save the `$now > $expires` guard always fired because $expires defaulted to 0, and on load `$expires - $now` turned a 0 expiry into a large-negative max-age that set_cookie() treated as already expired and discarded. Handle an expiry of 0 as a session cookie, matching how curl (and tools built on it, such as yt-dlp) read and write the cookies.txt format: write it with an expiry of 0 and keep it, and read a 0 expiry back as a session cookie rather than an expired one. Cookies with a real, past expiry are still dropped. This reimplements the fix originally proposed by Brian Gottreu in #5 against the current codebase, and adds round-trip test coverage. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
e65c1e8 to
066144f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
HTTP::Cookies::Netscapesilently dropped session cookies (cookies with no expiration) in both directions:$expiresdefaulted to0, so thereturn if $now > $expiresguard always fired and the cookie was never written.0expiry was turned into$expires - $now(a large negative max-age), whichset_cookie()treats as already-expired and discards.This change handles an expiry of
0as a session cookie, matching how curl — and tools built on it like yt-dlp — read and write thecookies.txtformat:0and kept;0expiry is read back as a session cookie (undef max-age) rather than an expired one;Per RFC 6265 §5.3, a cookie with neither
Max-AgenorExpiresis a session cookie that should be retained for the session — which is the behavior this restores for the Netscape format.Tests
t/netscape.tround-trips a session cookie and a persistent cookie through save/load, asserts the0expiry is written, and guards that an already-expired cookie is still not saved.t/cookies.t: the no-expiryfoo3cookie is a genuine session cookie (discard=0) and is now correctly retained, so the saved count is2(only the explicitDiscardcookie is dropped).Full suite passes (7 files, 128 tests).
Replaces #5
This reimplements the fix originally proposed in #5 against the current codebase. #5 can be closed once this lands. Many thanks to @gottreu (Brian Gottreu) for the original contribution and for surfacing the bug — the approach here follows their lead.
🤖 Generated with Claude Code