2020-04-26 13:49:31 +02:00
|
|
|
import net.http
|
|
|
|
import time
|
2020-04-14 03:34:05 +02:00
|
|
|
|
|
|
|
struct SetCookieTestCase {
|
|
|
|
cookie &http.Cookie
|
|
|
|
raw string
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ReadSetCookiesTestCase {
|
|
|
|
header map[string][]string
|
|
|
|
cookies []&http.Cookie
|
|
|
|
}
|
|
|
|
|
|
|
|
struct AddCookieTestCase {
|
|
|
|
cookie []&http.Cookie
|
|
|
|
raw string
|
|
|
|
}
|
|
|
|
|
|
|
|
const (
|
|
|
|
write_set_cookie_tests = [
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'cookie-1', value: 'v1'},
|
|
|
|
raw: 'cookie-1=v1'
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'cookie-2', value: 'two', max_age: 3600},
|
|
|
|
raw: 'cookie-2=two; Max-Age=3600'
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'cookie-3', value: 'three', domain: '.example.com'},
|
|
|
|
raw: 'cookie-3=three; domain=example.com'
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'cookie-4', value: 'four', path: '/restricted/'},
|
|
|
|
raw: 'cookie-4=four; path=/restricted/'
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'cookie-5', value: 'five', domain: 'wrong;bad.abc'},
|
|
|
|
raw: 'cookie-5=five'
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'cookie-6', value: 'six', domain: 'bad-.abc'},
|
|
|
|
raw: 'cookie-6=six'
|
|
|
|
},
|
|
|
|
// SetCookieTestCase{
|
|
|
|
// cookie: &http.Cookie{name: 'cookie-7', value: 'seven', domain: '127.0.0.1'},
|
|
|
|
// raw: 'cookie-7=seven; domain=127.0.0.1'
|
|
|
|
// },
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'cookie-8', value: 'eight', domain: '::1'},
|
|
|
|
raw: 'cookie-8=eight'
|
|
|
|
},
|
|
|
|
// {
|
|
|
|
// cookie: &http.Cookie{name: 'cookie-9', value: 'expiring', expires: time.unix(1257894000, 0)},
|
|
|
|
// 'cookie-9=expiring; Expires=Tue, 10 Nov 2009 23:00:00 GMT',
|
|
|
|
// },
|
|
|
|
// According to IETF 6265 Section 5.1.1.5, the year cannot be less than 1601
|
|
|
|
// SetCookieTestCase{
|
|
|
|
// cookie: &http.Cookie{name: 'cookie-10', value: 'expiring-1601', expires: time.parse('Mon, 01 Jan 1601 01:01:01 GMT')},
|
|
|
|
// raw: 'cookie-10=expiring-1601; Expires=Mon, 01 Jan 1601 01:01:01 GMT'
|
|
|
|
// },
|
|
|
|
// SetCookieTestCase{
|
|
|
|
// cookie: &http.Cookie{name: 'cookie-11', value: 'invalid-expiry', expires: time.parse('Mon, 01 Jan 1600 01:01:01 GMT')},
|
|
|
|
// raw: 'cookie-11=invalid-expiry'
|
|
|
|
// },
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'cookie-12', value: 'samesite-default', same_site: .same_site_default_mode},
|
|
|
|
raw: 'cookie-12=samesite-default; SameSite'
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'cookie-13', value: 'samesite-lax', same_site: .same_site_lax_mode},
|
|
|
|
raw: 'cookie-13=samesite-lax; SameSite=Lax'
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'cookie-14', value: 'samesite-strict', same_site: .same_site_strict_mode},
|
|
|
|
raw: 'cookie-14=samesite-strict; SameSite=Strict'
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'cookie-15', value: 'samesite-none', same_site: .same_site_none_mode},
|
|
|
|
raw: 'cookie-15=samesite-none; SameSite=None'
|
|
|
|
},
|
|
|
|
// The 'special' cookies have values containing commas or spaces which
|
|
|
|
// are disallowed by RFC 6265 but are common in the wild.
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'special-1', value: 'a z'},
|
|
|
|
raw: 'special-1=a z'
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'special-2', value: ' z'},
|
|
|
|
raw: 'special-2=" z"'
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'special-3', value: 'a '},
|
|
|
|
raw: 'special-3="a "'
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'special-4', value: ' '},
|
|
|
|
raw: 'special-4=" "'
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'special-5', value: 'a,z'},
|
|
|
|
raw: 'special-5=a,z'
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'special-6', value: ',z'},
|
|
|
|
raw: 'special-6=",z"'
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'special-7', value: 'a,'},
|
|
|
|
raw: 'special-7="a,"'
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'special-8', value: ','},
|
|
|
|
raw: 'special-8=","'
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'empty-value', value: ''},
|
|
|
|
raw: 'empty-value='
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: ''},
|
|
|
|
raw: ''
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: '\t'},
|
|
|
|
raw: ''
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: '\r'},
|
|
|
|
raw: ''
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'a\nb', value: 'v'},
|
|
|
|
raw: ''
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'a\nb', value: 'v'},
|
|
|
|
raw: ''
|
|
|
|
},
|
|
|
|
SetCookieTestCase{
|
|
|
|
cookie: &http.Cookie{name: 'a\rb', value: 'v'},
|
|
|
|
raw: ''
|
|
|
|
},
|
|
|
|
]
|
|
|
|
add_cookies_tests = [
|
|
|
|
AddCookieTestCase{
|
|
|
|
cookie: [],
|
|
|
|
raw: ""
|
|
|
|
},
|
|
|
|
AddCookieTestCase{
|
|
|
|
cookie: [&http.Cookie{name: "cookie-1", value: "v1"}],
|
|
|
|
raw: "cookie-1=v1"
|
|
|
|
},
|
|
|
|
AddCookieTestCase{
|
|
|
|
cookie: [
|
|
|
|
&http.Cookie{name: "cookie-1", value: "v1"},
|
|
|
|
&http.Cookie{name: "cookie-2", value: "v2"},
|
|
|
|
&http.Cookie{name: "cookie-3", value: "v3"}
|
|
|
|
],
|
|
|
|
raw: "cookie-1=v1; cookie-2=v2; cookie-3=v3"
|
|
|
|
}
|
|
|
|
]
|
|
|
|
read_set_cookies_tests = [
|
|
|
|
ReadSetCookiesTestCase{
|
|
|
|
header: {"Set-Cookie": ["Cookie-1=v1"]},
|
|
|
|
cookies: [&http.Cookie{name: "Cookie-1", value: "v1", raw: "Cookie-1=v1"}]
|
|
|
|
},
|
|
|
|
// ReadSetCookiesTestCase{
|
|
|
|
// header: {"Set-Cookie": ["NID=99=YsDT5i3E-CXax-; expires=Wed, 23-Nov-2011 01:05:03 GMT; path=/; domain=.google.ch; HttpOnly"]},
|
|
|
|
// cookies: [&http.Cookie{
|
|
|
|
// name: "NID",
|
|
|
|
// value: "99=YsDT5i3E-CXax-",
|
|
|
|
// path: "/",
|
|
|
|
// domain: ".google.ch",
|
|
|
|
// http_only: true,
|
|
|
|
// expires: time.parse_iso('Wed, 23-Nov-2011 01:05:03 GMT'),
|
|
|
|
// raw_expires: "Wed, 23-Nov-2011 01:05:03 GMT",
|
|
|
|
// raw: "NID=99=YsDT5i3E-CXax-; expires=Wed, 23-Nov-2011 01:05:03 GMT; path=/; domain=.google.ch; HttpOnly"
|
|
|
|
// }]
|
|
|
|
// },
|
|
|
|
// ReadSetCookiesTestCase{
|
|
|
|
// header: {"Set-Cookie": [".ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly"]},
|
|
|
|
// cookies: [&http.Cookie{
|
|
|
|
// name: ".ASPXAUTH",
|
|
|
|
// value: "7E3AA",
|
|
|
|
// path: "/",
|
|
|
|
// expires: time.parse_iso('Wed, 07-Mar-2012 14:25:06 GMT'),
|
|
|
|
// raw_expires: "Wed, 07-Mar-2012 14:25:06 GMT",
|
|
|
|
// http_only: true,
|
|
|
|
// raw: ".ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly"
|
|
|
|
// }]
|
|
|
|
// },
|
|
|
|
ReadSetCookiesTestCase{
|
|
|
|
header: {"Set-Cookie": ["ASP.NET_SessionId=foo; path=/; HttpOnly"]},
|
|
|
|
cookies: [&http.Cookie{
|
|
|
|
name: "ASP.NET_SessionId",
|
|
|
|
value: "foo",
|
|
|
|
path: "/",
|
|
|
|
http_only: true,
|
|
|
|
raw: "ASP.NET_SessionId=foo; path=/; HttpOnly"
|
|
|
|
}]
|
|
|
|
},
|
|
|
|
ReadSetCookiesTestCase{
|
|
|
|
header: {"Set-Cookie": ["samesitedefault=foo; SameSite"]},
|
|
|
|
cookies: [&http.Cookie{
|
|
|
|
name: "samesitedefault",
|
|
|
|
value: "foo",
|
|
|
|
same_site: .same_site_default_mode,
|
|
|
|
raw: "samesitedefault=foo; SameSite"
|
|
|
|
}]
|
|
|
|
},
|
|
|
|
ReadSetCookiesTestCase{
|
|
|
|
header: {"Set-Cookie": ["samesitelax=foo; SameSite=Lax"]},
|
|
|
|
cookies: [&http.Cookie{
|
|
|
|
name: "samesitelax",
|
|
|
|
value: "foo",
|
|
|
|
same_site: .same_site_lax_mode,
|
|
|
|
raw: "samesitelax=foo; SameSite=Lax"
|
|
|
|
}]
|
|
|
|
},
|
|
|
|
ReadSetCookiesTestCase{
|
|
|
|
header: {"Set-Cookie": ["samesitestrict=foo; SameSite=Strict"]},
|
|
|
|
cookies: [&http.Cookie{
|
|
|
|
name: "samesitestrict",
|
|
|
|
value: "foo",
|
|
|
|
same_site: .same_site_strict_mode,
|
|
|
|
raw: "samesitestrict=foo; SameSite=Strict"
|
|
|
|
}]
|
|
|
|
},
|
|
|
|
ReadSetCookiesTestCase{
|
|
|
|
header: {"Set-Cookie": ["samesitenone=foo; SameSite=None"]},
|
|
|
|
cookies: [&http.Cookie{
|
|
|
|
name: "samesitenone",
|
|
|
|
value: "foo",
|
|
|
|
same_site: .same_site_none_mode,
|
|
|
|
raw: "samesitenone=foo; SameSite=None"
|
|
|
|
}]
|
|
|
|
},
|
|
|
|
// Make sure we can properly read back the Set-Cookie headers we create
|
|
|
|
// for values containing spaces or commas:
|
|
|
|
ReadSetCookiesTestCase{
|
|
|
|
header: {"Set-Cookie": ['special-1=a z']},
|
|
|
|
cookies: [&http.Cookie{name: "special-1", value: "a z", raw: 'special-1=a z'}]
|
|
|
|
},
|
|
|
|
ReadSetCookiesTestCase{
|
|
|
|
header: {"Set-Cookie": ['special-2=" z"']},
|
|
|
|
cookies: [&http.Cookie{name: "special-2", value: " z", raw: 'special-2=" z"'}]
|
|
|
|
},
|
|
|
|
|
|
|
|
ReadSetCookiesTestCase{
|
|
|
|
header: {"Set-Cookie": ['special-3="a "']},
|
|
|
|
cookies: [&http.Cookie{name: "special-3", value: "a ", raw: 'special-3="a "'}]
|
|
|
|
},
|
|
|
|
ReadSetCookiesTestCase{
|
|
|
|
header: {"Set-Cookie": ['special-4=" "']},
|
|
|
|
cookies: [&http.Cookie{name: "special-4", value: " ", raw: 'special-4=" "'}]
|
|
|
|
},
|
|
|
|
ReadSetCookiesTestCase{
|
|
|
|
header: {"Set-Cookie": ['special-5=a,z']},
|
|
|
|
cookies: [&http.Cookie{name: "special-5", value: "a,z", raw: 'special-5=a,z'}]
|
|
|
|
},
|
|
|
|
ReadSetCookiesTestCase{
|
|
|
|
header: {"Set-Cookie": ['special-6=",z"']},
|
|
|
|
cookies: [&http.Cookie{name: "special-6", value: ",z", raw: 'special-6=",z"'}]
|
|
|
|
},
|
|
|
|
ReadSetCookiesTestCase{
|
|
|
|
header: {"Set-Cookie": ['special-7=","']},
|
|
|
|
cookies: [&http.Cookie{name: "special-7", value: ",", raw: 'special-8=","'}]
|
|
|
|
}
|
|
|
|
// TODO(bradfitz): users have reported seeing this in the
|
|
|
|
// wild, but do browsers handle it? RFC 6265 just says "don't
|
|
|
|
// do that" (section 3) and then never mentions header folding
|
|
|
|
// again.
|
|
|
|
// Header{"Set-Cookie": ["ASP.NET_SessionId=foo; path=/; HttpOnly, .ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly"]},
|
|
|
|
]
|
|
|
|
)
|
|
|
|
|
|
|
|
fn test_write_set_cookies() {
|
|
|
|
for _, tt in write_set_cookie_tests {
|
|
|
|
assert tt.cookie.str() == tt.raw
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test_read_set_cookies() {
|
|
|
|
for _, tt in read_set_cookies_tests {
|
|
|
|
h := tt.header['Set-Cookie'][0]
|
|
|
|
c := http.read_set_cookies(tt.header)
|
|
|
|
println(h)
|
|
|
|
println(c[0].str())
|
|
|
|
assert c[0].str() == h
|
|
|
|
}
|
|
|
|
}
|