///|
pub struct Header {
name : String
value : String
} derive(Debug, Eq)
///|
/// Ordered duplicate-preserving RFC-style header extraction; no MIME decoding.
pub fn headers(content : String) -> Array[Header] raise MailboxError {
let out : Array[Header] = []
for view in normalize_newlines(content).split("\n") {
let line = view.to_owned()
if line == "" {
break
}
if line.has_prefix(" ") || line.has_prefix("\t") {
if out.is_empty() {
raise Invalid("fold without header")
}
let old = out[out.length() - 1]
out[out.length() - 1] = {
name: old.name,
value: old.value + " " + line.trim().to_owned(),
}
continue
}
let pos = match line.find(":") {
Some(p) => p
None => raise Invalid("header missing colon")
}
let name = line[:pos].to_owned()
if name == "" {
raise Invalid("empty header name")
}
for c in name.iter() {
if c <= ' ' || c >= '\u007f' || c == ':' {
raise Invalid("invalid header name")
}
}
out.push({ name, value: line[pos + 1:].trim().to_owned(), })
}
out
}
///|
pub fn header_values(
content : String,
name : String,
) -> Array[String] raise MailboxError {
headers(content)
.filter(h => h.name.to_lower() == name.to_lower())
.map(h => h.value)
}