-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Combine cookies from original request and session file #932
Changes from all commits
0d9a5ce
773a65e
d30ce92
b21e8c2
87f6d23
07afd91
d58e1cd
bfea90f
5b98e4a
06af281
34a92b7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -530,7 +530,6 @@ Simple example: | |
$ http PUT httpbin.org/put name=John [email protected] | ||
|
||
.. code-block:: http | ||
|
||
PUT / HTTP/1.1 | ||
Accept: application/json, */*;q=0.5 | ||
Accept-Encoding: gzip, deflate | ||
|
@@ -1739,6 +1738,60 @@ exchange after it has been created, specify the session name via | |
# But it is not updated: | ||
$ http --session-read-only=./ro-session.json httpbin.org/headers Custom-Header:new-value | ||
|
||
Cookie Storage Behaviour | ||
------------------------ | ||
|
||
**TL;DR:** Cookie storage priority: Server response > Command line request > Session file | ||
|
||
To set a cookie within a Session there are three options: | ||
|
||
1. Get a `Set-Cookie` header in a response from a server | ||
|
||
.. code-block:: bash | ||
|
||
$ http --session=./session.json httpbin.org/cookie/set?foo=bar | ||
|
||
2. Set the cookie name and value through the command line as seen in `cookies`_ | ||
|
||
.. code-block:: bash | ||
|
||
$ http --session=./session.json httpbin.org/headers Cookie:foo=bar | ||
|
||
3. Manually set cookie parameters in the json file of the session | ||
|
||
.. code-block:: json | ||
|
||
{ | ||
"__meta__": { | ||
"about": "HTTPie session file", | ||
"help": "https://httpie.org/doc#sessions", | ||
"httpie": "2.2.0-dev" | ||
}, | ||
"auth": { | ||
"password": null, | ||
"type": null, | ||
"username": null | ||
}, | ||
"cookies": { | ||
"foo": { | ||
"expires": null, | ||
"path": "/", | ||
"secure": false, | ||
"value": "bar" | ||
} | ||
} | ||
} | ||
|
||
Cookies will be set in the session file with the priority specified above. For example, a cookie | ||
set through the command line will overwrite a cookie of the same name stored | ||
in the session file. If the server returns a `Set-Cookie` header with a | ||
cookie of the same name, the returned cookie will overwrite the preexisting cookie. | ||
|
||
Expired cookies are never stored. If a cookie in a session file expires, it will be removed before | ||
sending a new request. If the server expires an existing cookie, it will also be removed from the | ||
session file. | ||
|
||
|
||
Config | ||
====== | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,8 @@ | |
""" | ||
import os | ||
import re | ||
|
||
from http.cookies import SimpleCookie | ||
from pathlib import Path | ||
from typing import Iterable, Optional, Union | ||
from urllib.parse import urlsplit | ||
|
@@ -76,7 +78,13 @@ def update_headers(self, request_headers: RequestHeadersDict): | |
continue # Ignore explicitly unset headers | ||
|
||
value = value.decode('utf8') | ||
if name == 'User-Agent' and value.startswith('HTTPie/'): | ||
if name.lower() == 'user-agent' and value.startswith('HTTPie/'): | ||
continue | ||
|
||
if name.lower() == 'cookie': | ||
for cookie_name, morsel in SimpleCookie(value).items(): | ||
self['cookies'][cookie_name] = {'value': morsel.value} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is missing now is to define & document & test priority rules. With this implementation, request cookies seem to win over response cookies. But it feels like it should be the other way, i.e., last seen cookies should be the ones that get stored in the session. What do you think? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We added a new test, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After our call this morning, @gmelodie and I discussed the possible behaviours of cookies expiring in sessions and which cookies should take precedent. Our understanding was regardless of the expiry behaviour, the storage priority should still be server set > command line set > session file. For that reason, we didn't write further related tests. Here's a couple of example cases illustrating why we didn't think further tests were necessary:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Agree 👍🏻 |
||
del request_headers[name] | ||
continue | ||
|
||
for prefix in SESSION_IGNORED_HEADER_PREFIXES: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We tried to emphasize lines 12-18 in this code block using :emphasize-lines:, but we weren't able to get it to render properly.