101 lines
2.4 KiB
Rust
101 lines
2.4 KiB
Rust
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
|
pub enum Version {
|
|
HTTP1_1,
|
|
}
|
|
impl core::fmt::Display for Version {
|
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
|
match self {
|
|
Version::HTTP1_1 => write!(f, "HTTP/1.1"),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
|
pub struct RequestLine<'a> {
|
|
pub method: &'a str,
|
|
pub target: &'a str,
|
|
pub version: Version,
|
|
}
|
|
|
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
|
pub struct StatusLine<'a> {
|
|
pub version: Version,
|
|
pub status_code: u16,
|
|
pub status_text: &'a str,
|
|
}
|
|
|
|
/// Headers that impact the state of the connection
|
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
|
pub enum HeaderSpecial {
|
|
TransferEncodingChunked,
|
|
ContentLength(usize),
|
|
}
|
|
|
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
|
pub struct HeaderOther<'a> {
|
|
pub name: &'a str,
|
|
pub value: &'a [u8],
|
|
}
|
|
|
|
impl<'a, Name, Value> From<(&'a Name, &'a Value)> for HeaderOther<'a>
|
|
where
|
|
Name: AsRef<str> + ?Sized,
|
|
Value: AsRef<[u8]> + ?Sized,
|
|
{
|
|
fn from(value: (&'a Name, &'a Value)) -> Self {
|
|
let (name, value) = value;
|
|
let name = name.as_ref();
|
|
let value = value.as_ref();
|
|
|
|
Self { name, value }
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
|
pub enum Header<'a> {
|
|
Special(HeaderSpecial),
|
|
Other(HeaderOther<'a>),
|
|
}
|
|
|
|
impl<'a> From<HeaderSpecial> for Header<'a> {
|
|
fn from(value: HeaderSpecial) -> Self {
|
|
Self::Special(value)
|
|
}
|
|
}
|
|
|
|
impl<'a> From<HeaderOther<'a>> for Header<'a> {
|
|
fn from(value: HeaderOther<'a>) -> Self {
|
|
Self::Other(value)
|
|
}
|
|
}
|
|
|
|
impl<'a, Name, Value> From<(&'a Name, &'a Value)> for Header<'a>
|
|
where
|
|
Name: AsRef<str> + ?Sized,
|
|
Value: AsRef<[u8]> + ?Sized,
|
|
{
|
|
fn from(value: (&'a Name, &'a Value)) -> Self {
|
|
let (name, value) = value;
|
|
let name = name.as_ref();
|
|
let value = value.as_ref();
|
|
|
|
match () {
|
|
_ if name.eq_ignore_ascii_case("transfer-encoding")
|
|
&& value.eq_ignore_ascii_case(b"chunked") =>
|
|
{
|
|
Header::Special(HeaderSpecial::TransferEncodingChunked)
|
|
},
|
|
_ if name.eq_ignore_ascii_case("content-length") => {
|
|
match core::str::from_utf8(value)
|
|
.ok()
|
|
.and_then(|s| s.parse().ok())
|
|
{
|
|
Some(v) => Header::Special(HeaderSpecial::ContentLength(v)),
|
|
_ => Header::Other(HeaderOther { name, value }),
|
|
}
|
|
},
|
|
_ => Header::Other(HeaderOther { name, value }),
|
|
}
|
|
}
|
|
}
|