Skip to content

Fix (#998): Will not expire/delete cookie from session when Set-Cookie only sets Max-Age=0 without Expires - #1029

Merged
jkbrzt merged 5 commits into
httpie:masterfrom
luckydenis:issue998
Feb 6, 2021
Merged

Fix (#998): Will not expire/delete cookie from session when Set-Cookie only sets Max-Age=0 without Expires#1029
jkbrzt merged 5 commits into
httpie:masterfrom
luckydenis:issue998

Conversation

@luckydenis

Copy link
Copy Markdown
Contributor

Summary:
The reason why the cookie state information is lost is that when a response is received, the query library does not process max-age=0. It was decided to report the problem to the requests community and implement a temporary solution.

Done:

@codecov-io

codecov-io commented Feb 5, 2021

Copy link
Copy Markdown

Codecov Report

Merging #1029 (d4e57b2) into master (cf78a12) will increase coverage by 0.01%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1029      +/-   ##
==========================================
+ Coverage   95.55%   95.56%   +0.01%     
==========================================
  Files          61       61              
  Lines        3937     3947      +10     
==========================================
+ Hits         3762     3772      +10     
  Misses        175      175              
Impacted Files Coverage Δ
httpie/utils.py 97.72% <100.00%> (+0.35%) ⬆️
tests/test_sessions.py 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update cf78a12...d4e57b2. Read the comment docs.

@luckydenis

Copy link
Copy Markdown
Contributor Author

It looks like there was a bug in the test environment. 😊

Comment thread httpie/utils.py
@jkbrzt
jkbrzt merged commit 3c07a25 into httpie:master Feb 6, 2021
jkbrzt added a commit that referenced this pull request Feb 6, 2021
@jkbrzt

jkbrzt commented Feb 6, 2021

Copy link
Copy Markdown
Member

Thanks, @luckydenis 🥧

@luckydenis

Copy link
Copy Markdown
Contributor Author

@jakubroztocil, Thank you, I hope to participate in your wonderful project again ^_^

alutoin-cloudamite added a commit to alutoin-cloudamite/cli that referenced this pull request Jul 31, 2026
Completes the fix for httpie#998, which reported that a cookie carrying only
`Max-Age=0` (no `Expires`) was never removed from the session file. PR httpie#1029
addressed that by translating `max-age` into `expires`, gated on
`max_age.isdigit()`.

`str.isdigit()` is False for any negative value, so `Max-Age=-1` still never
receives an `expires` key, is never recognised as expired by
`get_expired_cookies()`, and is never removed -- the same symptom httpie#998
described, for the other common deletion idiom. HTTPie keeps sending a cookie
the server has told it to delete.

RFC 6265 section 5.2.2: "If delta-seconds is less than or equal to zero, let
expiry-time be the earliest representable date and time."

Parse with `int()` instead, so negative deltas are honoured while unparseable
values are still ignored rather than raising -- note that a narrower fix such as
`max_age.lstrip('-').isdigit()` would make `int('--1')` throw, which the new
test pins.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
alutoin-cloudamite added a commit to alutoin-cloudamite/cli that referenced this pull request Jul 31, 2026
Completes the fix for httpie#998, which reported that a cookie carrying only
`Max-Age=0` (no `Expires`) was never removed from the session file. httpie#1029
addressed that by translating `max-age` into `expires` in
`_max_age_to_expires()`, gated on `max_age.isdigit()`.

`str.isdigit()` is False for any negative value, so `Max-Age=-1` still never
receives an `expires` key, is never recognised as expired by
`get_expired_cookies()`, and is never removed -- the same symptom httpie#998
described, for the other common deletion idiom. HTTPie keeps sending a cookie
the server has told it to delete.

RFC 6265 section 5.2.2: "If delta-seconds is less than or equal to zero, let
expiry-time be the earliest representable date and time."

Parse with `int()` instead, so negative deltas are honoured while unparseable
values are still ignored rather than raising -- note that a narrower fix such as
`max_age.lstrip('-').isdigit()` would make `int('--1')` throw, which the new
test pins. This matches the standard library, which parses `max-age` with
`int()` in `http.cookiejar`.

Also rewrites the docstring. It read `HACK/FIXME: <psf/requests#5743>`, but that
issue was declined as a no-op rather than fixed, so this is not a workaround
awaiting upstream removal. The docstring now records the RFC rule, and that the
function is only load-bearing for pre-3.1.0 session layouts: those stored
cookies as a domainless dict, so `http.cookiejar`'s `clear(domain, path, name)`
could not match them, whereas since httpie#1335 the layout carries domain and path and
the cookiejar removes expired cookies by itself. Removing this function
therefore means dropping support for the old layout first.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
alutoin-cloudamite added a commit to alutoin-cloudamite/cli that referenced this pull request Jul 31, 2026
Completes the fix for httpie#998, which reported that a cookie carrying only
`Max-Age=0` (no `Expires`) was never removed from the session file. httpie#1029
addressed that by translating `max-age` into `expires` in
`_max_age_to_expires()`, gated on `max_age.isdigit()`.

`str.isdigit()` is False for any negative value, so `Max-Age=-1` still never
receives an `expires` key, is never recognised as expired by
`get_expired_cookies()`, and is never removed -- the same symptom httpie#998
described, for the other common deletion idiom. HTTPie keeps sending a cookie
the server has told it to delete.

RFC 6265 section 5.2.2: "If delta-seconds is less than or equal to zero, let
expiry-time be the earliest representable date and time."

Parse with `int()` instead, so negative deltas are honoured while unparseable
values are still ignored rather than raising -- note that a narrower fix such as
`max_age.lstrip('-').isdigit()` would make `int('--1')` throw, which the new
test pins. This matches the standard library, which parses `max-age` with
`int()` in `http.cookiejar`.

Also rewrites the docstring. It read `HACK/FIXME: <psf/requests#5743>`, but that
issue was declined as a no-op rather than fixed, so this is not a workaround
awaiting upstream removal. The docstring now records the RFC rule, and that the
function is only load-bearing for pre-3.1.0 session layouts: those stored
cookies as a domainless dict, so `http.cookiejar`'s `clear(domain, path, name)`
could not match them, whereas since 3.1.0 each cookie is bound to a domain
(httpie#1312) and the cookiejar removes expired ones by itself. Removing this function
therefore means dropping support for the old layout first.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
alutoin-cloudamite added a commit to alutoin-cloudamite/cli that referenced this pull request Jul 31, 2026
Completes the fix for httpie#998, which reported that a cookie carrying only
`Max-Age=0` (no `Expires`) was never removed from the session file. httpie#1029
addressed that by translating `max-age` into `expires` in
`_max_age_to_expires()`, gated on `max_age.isdigit()`.

`str.isdigit()` is False for any negative value, so `Max-Age=-1` still never
receives an `expires` key, is never recognised as expired by
`get_expired_cookies()`, and is never removed -- the same symptom httpie#998
described, for the other common deletion idiom. HTTPie keeps sending a cookie
the server has told it to delete.

RFC 6265 section 5.2.2: "If delta-seconds is less than or equal to zero, let
expiry-time be the earliest representable date and time."

Parse with `int()` instead, so negative deltas are honoured while unparseable
values are still ignored rather than raising -- note that a narrower fix such as
`max_age.lstrip('-').isdigit()` would make `int('--1')` throw, which the new
test pins. This matches the standard library, which parses `max-age` with
`int()` in `http.cookiejar`.

Also rewrites the docstring. It read `HACK/FIXME: <psf/requests#5743>`, but that
issue was declined as a no-op rather than fixed, so this is not a workaround
awaiting upstream removal. The docstring now records the RFC rule, and that the
function is only load-bearing for pre-3.1.0 session layouts: those stored
cookies as a domainless dict, so `http.cookiejar`'s `clear(domain, path, name)`
could not match them, whereas since 3.1.0 each cookie is bound to a domain
(httpie#1312) and the cookiejar removes expired ones by itself. Removing this function
therefore means dropping support for the old layout first.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

4 participants