Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
This document records all notable changes to [HTTPie](https://httpie.io).
This project adheres to [Semantic Versioning](https://semver.org/).

## Unreleased

- Honor `Max-Age` over `Expires` when removing expired session cookies.

## [3.2.4](https://github.com/httpie/cli/compare/3.2.3...3.2.4) (2024-11-01)

- Fix default certs loading and unpin `requests`. ([#1596](https://github.com/httpie/cli/issues/1596))
Expand Down
2 changes: 0 additions & 2 deletions httpie/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,6 @@ def _max_age_to_expires(cookies, now):

"""
for cookie in cookies:
if 'expires' in cookie:
continue
max_age = cookie.get('max-age')
if max_age and max_age.isdigit():
cookie['expires'] = now + float(max_age)
Expand Down
33 changes: 30 additions & 3 deletions tests/test_sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,13 +394,41 @@ def test_expired_cookies(self, httpbin):
assert 'cookie1' in updated_session['cookies']
assert 'cookie2' not in updated_session['cookies']

def test_session_keeps_cookie_when_max_age_overrides_expired_date(self, localhost_http_server):
http(
'--session', str(self.session_path),
localhost_http_server + '/cookies/set',
'cookie2==bar; Max-Age=3600; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Path=/',
)
r = http(
'--session', str(self.session_path),
'--print=H',
localhost_http_server + '/cookies',
)
assert 'cookie2=bar' in r

def test_get_expired_cookies_using_max_age(self):
cookies = 'one=two; Max-Age=0; path=/; domain=.tumblr.com; HttpOnly'
expected_expired = [
{'name': 'one', 'path': '/'}
]
assert get_expired_cookies(cookies, now=None) == expected_expired

@pytest.mark.parametrize(
'expires, max_age, expired',
[
('Thu, 01-Jan-1970 00:00:00 GMT', '3600', False),
('Fri, 12 Jun 2020 12:28:55 GMT', '0', True),
('invalid', '0', True),
('Thu, 01-Jan-1970 00:00:00 GMT', 'invalid', True),
('Fri, 12 Jun 2020 12:28:55 GMT', 'invalid', False),
]
)
def test_max_age_takes_precedence_over_expires(self, expires, max_age, expired):
cookies = f'one=two; Expires={expires}; Max-Age={max_age}; Path=/'
expected = [{'name': 'one', 'path': '/'}] if expired else []
assert get_expired_cookies(cookies, now=1000.0) == expected

@pytest.mark.parametrize(
'cookies, now, expected_expired',
[
Expand All @@ -426,11 +454,10 @@ def test_get_expired_cookies_using_max_age(self):
]
),
(
# Checks we gracefully ignore expires date in invalid format.
# <https://github.com/httpie/cli/issues/963>
# A valid Max-Age still applies when Expires is malformed.
'pfg=; Expires=Sat, 19-Sep-2020 06:58:14 GMT+0000; Max-Age=0; path=/; domain=.tumblr.com; secure; HttpOnly',
None,
[]
[{'name': 'pfg', 'path': '/'}]
),
(
'hello=world; Path=/; Expires=Fri, 12 Jun 2020 12:28:55 GMT; HttpOnly',
Expand Down
Loading