///|
fn parse_set_cookie(str : StringView) -> @http.Cookie raise {
guard str.find("=") is Some(name_end) else {
fail("Invalid cookie: no '=' found")
}
let name = str[:name_end].to_owned()
guard str[name_end + 1:].find(";") is Some(value_end) else {
Cookie(name, str[name_end + 1:].to_owned())
}
let value_end = name_end + 1 + value_end
let value = str[name_end + 1:value_end].to_owned()
let mut path = None
let mut expires_raw = None
let mut max_age = None
let mut domain = None
let mut secure = false
let mut http_only = false
let extensions = []
for parsed = value_end + 1 {
let attr_end = if str[parsed:].find(";") is Some(attr_end) {
parsed + attr_end
} else {
str.length()
}
let attr = str[parsed:attr_end].trim()
if attr.find("=") is Some(attr_name_end) {
let name = attr[:attr_name_end]
let value = attr[attr_name_end + 1:]
match name.to_lower() {
"path" => path = Some(value.to_owned())
"expires" => expires_raw = Some(value.to_owned())
"max-age" => {
let value = @string.parse_int64(value) catch {
_ => fail("Invalid cookie: invalid max-age")
}
max_age = Some(value)
}
"domain" => domain = Some(value.to_owned())
_ => extensions.push(attr.to_owned())
}
} else {
match attr.to_lower() {
"secure" => secure = true
"httponly" => http_only = true
_ => extensions.push(attr.to_owned())
}
}
if attr_end == str.length() {
break
} else {
continue attr_end + 1
}
}
Cookie(
name,
value,
path?,
expires_raw?,
max_age?,
domain?,
secure~,
http_only~,
extensions~,
)
}
///|
fn cookie_to_header_value(cookie : @http.Cookie) -> String {
let buf = StringBuilder()
buf.write_string(cookie.name)
buf.write_string("=")
buf.write_string(cookie.value)
if cookie.path is Some(path) {
buf.write_string("; Path=")
buf.write_string(path)
}
if cookie.expires_raw is Some(expires_raw) {
buf.write_string("; Expires=")
buf.write_string(expires_raw)
}
if cookie.max_age is Some(max_age) {
buf.write_string("; Max-Age=")
buf.write_string(max_age.to_string())
}
if cookie.domain is Some(domain) {
buf.write_string("; Domain=")
buf.write_string(domain)
}
if cookie.secure {
buf.write_string("; Secure")
}
if cookie.http_only {
buf.write_string("; HttpOnly")
}
for ext in cookie.extensions {
buf.write_string("; ")
buf.write_string(ext)
}
buf.to_string()
}
///|
fn parse_cookie(str : StringView) -> Map[String, String] {
let cookies = Map([])
for parsed = 0 {
let pair_end = if str[parsed:].find(";") is Some(pair_end) {
parsed + pair_end
} else {
str.length()
}
let pair = str[parsed:pair_end].trim()
if pair.find("=") is Some(name_end) {
let name = pair[:name_end].trim()
if !name.is_empty() {
cookies[name.to_owned()] = pair[name_end + 1:].trim().to_owned()
}
}
if pair_end == str.length() {
break
} else {
continue pair_end + 1
}
}
cookies
}