pub(crate) mod io;
pub(crate) fn is_tchar(b: u8) -> bool {
b.is_ascii_alphanumeric()
|| b == b'!'
|| b == b'#'
|| b == b'$'
|| b == b'%'
|| b == b'&'
|| b == b'\''
|| b == b'*'
|| b == b'+'
|| b == b'-'
|| b == b'.'
|| b == b'^'
|| b == b'_'
|| b == b'`'
|| b == b'|'
|| b == b'~'
}
pub(crate) fn is_token(name: &str) -> bool {
!name.is_empty() && name.bytes().all(is_tchar)
}
pub(crate) fn is_field_vchar(b: u8) -> bool {
b == b'\t' || b >= 0x20
}
pub(crate) fn is_field_value(value: &[u8]) -> bool {
if value.is_empty() {
true
} else {
let first: u8 = *value.first().unwrap();
let last: u8 = *value.last().unwrap();
first != b' '
&& first != b'\t'
&& last != b' '
&& last != b'\t'
&& value.iter().all(|b| is_field_vchar(*b))
}
}
pub(crate) fn is_request_target_char(b: u8) -> bool {
(0x21_u8..=0x7F_u8).contains(&b)
}
pub(crate) fn is_request_target(req: &str) -> bool {
!req.is_empty() && req.bytes().all(is_request_target_char)
}
pub(crate) fn is_connection_close(headers: &[crate::Header<'_>]) -> bool {
for header in headers {
if header.name.eq_ignore_ascii_case("connection") {
for mut option in header.value.split(|b| *b == b',') {
while option.first() == Some(&b' ') || option.first() == Some(&b'\t') {
option = &option[1..];
}
while option.last() == Some(&b' ') || option.last() == Some(&b'\t') {
option = &option[..option.len() - 1];
}
if option.eq_ignore_ascii_case(b"close") {
return true;
}
}
}
}
false
}