Support ascii_whitespaces separator in importing cookie.

This commit is contained in:
Jean-Christophe Amiel 2025-11-14 11:47:24 +01:00
parent 31bf0a699d
commit e3dbe03d11
No known key found for this signature in database
GPG Key ID: 07FF11CFD55356CC
4 changed files with 43 additions and 2 deletions

View File

@ -8,7 +8,7 @@ Set-Cookie: LSID=DQAAAKEaem_vYg; Expires=Thu, 13 Jan 2078 22:23:01 GMT; HttpOnly
Set-Cookie: HSID=AYQEVnDKrdst; Domain=localhost; Expires=Thu, 13 Jan 2078 22:23:01 GMT; HttpOnly; Path=/
Set-Cookie: SSID=Ap4PGTEq; Domain=localhost; Expires=Thu, 13 Jan 2078 22:23:01 GMT; HttpOnly; Path=/
[Asserts]
header "Set-Cookie" count == 3
header "Set-Cookie" count == 4
cookie "LSID" == "DQAAAKEaem_vYg"
cookie "LSID[Value]" == "DQAAAKEaem_vYg"
cookie "LSID[Expires]" exists
@ -19,3 +19,4 @@ cookie "LSID[Path]" == "/accounts"
cookie "LSID[Secure]" not exists
cookie "LSID[HttpOnly]" exists
cookie "LSID[SameSite]" not exists
cookie "foo" == "\"a b c\""

View File

@ -5,3 +5,4 @@
#HttpOnly_localhost FALSE /accounts FALSE <<<(17\d{8}|3409338181)>>> LSID DQAAAKEaem_vYg
#HttpOnly_.localhost TRUE / FALSE <<<(17\d{8}|3409338181)>>> HSID AYQEVnDKrdst
#HttpOnly_.localhost TRUE / FALSE <<<(17\d{8}|3409338181)>>> SSID Ap4PGTEq
.localhost TRUE / FALSE <<<(17\d{8}|3093675001)>>> foo "a b c"

View File

@ -28,4 +28,12 @@ def set_cookie_jar():
expires="Thu, 13 Jan 2078 22:23:01 GMT",
httponly=True,
)
resp.set_cookie(
"foo",
"a b c",
domain="localhost",
path="/",
expires="Thu, 13 Jan 2068 10:10:01 GMT",
httponly=False,
)
return resp

View File

@ -114,7 +114,10 @@ impl Cookie {
/// Creates a [`Cookie`] from a Netscape cookie formatted string.
pub fn from_netscape_str(s: &str) -> Result<Self, ParseCookieError> {
let tokens = s.split_ascii_whitespace().collect::<Vec<&str>>();
// The Netscape format uses tab as separator, we want also to import cookie with a space
// separator (for inline use in Hurl files with `@cookie_storage` command for instance).
// The format has only 7 values, and the last token can include whitespaces.
let tokens: Vec<&str> = s.splitn(7, |c: char| c.is_ascii_whitespace()).collect();
let (http_only, domain) = if let Some(&v) = tokens.first() {
if let Some(domain) = v.strip_prefix("#HttpOnly_") {
(true, domain.to_string())
@ -229,6 +232,34 @@ mod tests {
}
);
assert_eq!(
Cookie::from_netscape_str("localhost FALSE / FALSE 1 cookie3 value3").unwrap(),
Cookie {
domain: "localhost".to_string(),
include_subdomain: "FALSE".to_string(),
path: "/".to_string(),
https: "FALSE".to_string(),
expires: "1".to_string(),
name: "cookie3".to_string(),
value: "value3".to_string(),
http_only: false,
}
);
assert_eq!(
Cookie::from_netscape_str("#HttpOnly_localhost FALSE / FALSE 1 cookie3 a b c").unwrap(),
Cookie {
domain: "localhost".to_string(),
include_subdomain: "FALSE".to_string(),
path: "/".to_string(),
https: "FALSE".to_string(),
expires: "1".to_string(),
name: "cookie3".to_string(),
value: "a b c".to_string(),
http_only: true,
}
);
assert_eq!(
Cookie::from_netscape_str("xxx").err().unwrap(),
ParseCookieError