use http::{header, HeaderMap};
use buffet::Piece;
pub type Headers = HeaderMap<Piece>;
pub trait HeadersExt {
fn content_length(&self) -> Option<u64>;
fn is_connection_close(&self) -> bool;
fn is_chunked_transfer_encoding(&self) -> bool;
fn expects_100_continue(&self) -> bool;
}
impl HeadersExt for HeaderMap<Piece> {
fn content_length(&self) -> Option<u64> {
self.get(header::CONTENT_LENGTH)
.and_then(|s| from_digits(s))
}
fn is_connection_close(&self) -> bool {
self.get(header::CONNECTION)
.map_or(false, |value| value.eq_ignore_ascii_case(b"close"))
}
fn is_chunked_transfer_encoding(&self) -> bool {
self.get(header::TRANSFER_ENCODING)
.map_or(false, |value| value.eq_ignore_ascii_case(b"chunked"))
}
fn expects_100_continue(&self) -> bool {
self.get(header::EXPECT)
.map_or(false, |value| value.eq_ignore_ascii_case(b"100-continue"))
}
}
fn from_digits(bytes: &[u8]) -> Option<u64> {
let mut result = 0u64;
const RADIX: u64 = 10;
if bytes.is_empty() {
return None;
}
for &b in bytes {
match b {
b'0'..=b'9' => {
result = result.checked_mul(RADIX)?;
result = result.checked_add((b - b'0') as u64)?;
}
_ => {
return None;
}
}
}
Some(result)
}