From 44419afc16770ab90ac2bc9606c153d658b258ab Mon Sep 17 00:00:00 2001 From: yggverse Date: Sat, 22 Feb 2025 21:56:43 +0200 Subject: [PATCH] use global `Header` trait --- src/request/titan.rs | 21 ++----------- src/response/certificate/expected.rs | 30 +++++++------------ src/response/certificate/not_authorized.rs | 30 +++++++------------ src/response/certificate/not_valid.rs | 30 +++++++------------ src/response/failure/permanent/bad_request.rs | 30 +++++++------------ src/response/failure/permanent/general.rs | 30 +++++++------------ src/response/failure/permanent/gone.rs | 30 +++++++------------ src/response/failure/permanent/not_found.rs | 30 +++++++------------ .../permanent/proxy_request_refused.rs | 30 +++++++------------ src/response/failure/temporary/cgi_error.rs | 30 +++++++------------ src/response/failure/temporary/general.rs | 30 +++++++------------ src/response/failure/temporary/proxy_error.rs | 30 +++++++------------ .../failure/temporary/server_unavailable.rs | 30 +++++++------------ src/response/failure/temporary/slow_down.rs | 30 +++++++------------ src/response/input/default.rs | 30 +++++++------------ src/response/input/sensitive.rs | 30 +++++++------------ src/response/redirect/permanent.rs | 27 ++++------------- src/response/redirect/temporary.rs | 27 ++++------------- 18 files changed, 163 insertions(+), 362 deletions(-) diff --git a/src/request/titan.rs b/src/request/titan.rs index 2c47c85..591bb16 100644 --- a/src/request/titan.rs +++ b/src/request/titan.rs @@ -13,26 +13,11 @@ pub struct Titan<'a> { impl<'a> Titan<'a> { pub fn from_bytes(buffer: &'a [u8]) -> Result { + use crate::Header; use regex::Regex; - - let mut l: usize = 0; - - for b in buffer { - l += 1; - if l > 1024 { - bail!("Max header length reached!") - } - if *b == b'\r' { - continue; - } - if *b == b'\n' { - break; - } - } - - let header = from_utf8(&buffer[..l])?; + let header = from_utf8(buffer.header_bytes()?)?; Ok(Self { - data: &buffer[l..], + data: &buffer[header.len() + 2..], size: match Regex::new(r"size=(\d+)")?.captures(header) { Some(c) => match c.get(1) { Some(v) => match v.as_str().parse::() { diff --git a/src/response/certificate/expected.rs b/src/response/certificate/expected.rs index 63bd266..ae55786 100644 --- a/src/response/certificate/expected.rs +++ b/src/response/certificate/expected.rs @@ -11,31 +11,21 @@ impl Expected { /// Build `Self` from UTF-8 header bytes /// * expected buffer includes leading status code, message, CRLF pub fn from_bytes(buffer: &[u8]) -> Result { - // calculate length once - let len = buffer.len(); - // validate headers for this response type - if !(3..=1024).contains(&len) { - bail!("Unexpected header length") - } - if buffer - .get(..2) + use crate::Header; + let h = buffer.header_bytes()?; + if h.get(..2) .is_none_or(|c| c[0] != CODE[0] || c[1] != CODE[1]) { bail!("Invalid status code") } - // collect data bytes - let mut m = Vec::with_capacity(len); - for b in buffer[3..].iter() { - if *b == b'\r' { - continue; - } - if *b == b'\n' { - break; - } - m.push(*b) - } Ok(Self { - message: String::from_utf8(m).map(|m| if m.is_empty() { None } else { Some(m) })?, + message: String::from_utf8((&h[3..]).to_vec()).map(|m| { + if m.is_empty() { + None + } else { + Some(m) + } + })?, }) } diff --git a/src/response/certificate/not_authorized.rs b/src/response/certificate/not_authorized.rs index f8606f8..b8386e1 100644 --- a/src/response/certificate/not_authorized.rs +++ b/src/response/certificate/not_authorized.rs @@ -11,31 +11,21 @@ impl NotAuthorized { /// Build `Self` from UTF-8 header bytes /// * expected buffer includes leading status code, message, CRLF pub fn from_bytes(buffer: &[u8]) -> Result { - // calculate length once - let len = buffer.len(); - // validate headers for this response type - if !(3..=1024).contains(&len) { - bail!("Unexpected header length") - } - if buffer - .get(..2) + use crate::Header; + let h = buffer.header_bytes()?; + if h.get(..2) .is_none_or(|c| c[0] != CODE[0] || c[1] != CODE[1]) { bail!("Invalid status code") } - // collect data bytes - let mut m = Vec::with_capacity(len); - for b in buffer[3..].iter() { - if *b == b'\r' { - continue; - } - if *b == b'\n' { - break; - } - m.push(*b) - } Ok(Self { - message: String::from_utf8(m).map(|m| if m.is_empty() { None } else { Some(m) })?, + message: String::from_utf8((&h[3..]).to_vec()).map(|m| { + if m.is_empty() { + None + } else { + Some(m) + } + })?, }) } diff --git a/src/response/certificate/not_valid.rs b/src/response/certificate/not_valid.rs index cf89e62..330ccd9 100644 --- a/src/response/certificate/not_valid.rs +++ b/src/response/certificate/not_valid.rs @@ -11,31 +11,21 @@ impl NotValid { /// Build `Self` from UTF-8 header bytes /// * expected buffer includes leading status code, message, CRLF pub fn from_bytes(buffer: &[u8]) -> Result { - // calculate length once - let len = buffer.len(); - // validate headers for this response type - if !(3..=1024).contains(&len) { - bail!("Unexpected header length") - } - if buffer - .get(..2) + use crate::Header; + let h = buffer.header_bytes()?; + if h.get(..2) .is_none_or(|c| c[0] != CODE[0] || c[1] != CODE[1]) { bail!("Invalid status code") } - // collect data bytes - let mut m = Vec::with_capacity(len); - for b in buffer[3..].iter() { - if *b == b'\r' { - continue; - } - if *b == b'\n' { - break; - } - m.push(*b) - } Ok(Self { - message: String::from_utf8(m).map(|m| if m.is_empty() { None } else { Some(m) })?, + message: String::from_utf8((&h[3..]).to_vec()).map(|m| { + if m.is_empty() { + None + } else { + Some(m) + } + })?, }) } diff --git a/src/response/failure/permanent/bad_request.rs b/src/response/failure/permanent/bad_request.rs index ea413cf..828ec23 100644 --- a/src/response/failure/permanent/bad_request.rs +++ b/src/response/failure/permanent/bad_request.rs @@ -11,31 +11,21 @@ impl BadRequest { /// Build `Self` from UTF-8 header bytes /// * expected buffer includes leading status code, message, CRLF pub fn from_bytes(buffer: &[u8]) -> Result { - // calculate length once - let len = buffer.len(); - // validate headers for this response type - if !(3..=1024).contains(&len) { - bail!("Unexpected header length") - } - if buffer - .get(..2) + use crate::Header; + let h = buffer.header_bytes()?; + if h.get(..2) .is_none_or(|c| c[0] != CODE[0] || c[1] != CODE[1]) { bail!("Invalid status code") } - // collect data bytes - let mut m = Vec::with_capacity(len); - for b in buffer[3..].iter() { - if *b == b'\r' { - continue; - } - if *b == b'\n' { - break; - } - m.push(*b) - } Ok(Self { - message: String::from_utf8(m).map(|m| if m.is_empty() { None } else { Some(m) })?, + message: String::from_utf8((&h[3..]).to_vec()).map(|m| { + if m.is_empty() { + None + } else { + Some(m) + } + })?, }) } diff --git a/src/response/failure/permanent/general.rs b/src/response/failure/permanent/general.rs index b0c2e6e..7bd181b 100644 --- a/src/response/failure/permanent/general.rs +++ b/src/response/failure/permanent/general.rs @@ -11,31 +11,21 @@ impl General { /// Build `Self` from UTF-8 header bytes /// * expected buffer includes leading status code, message, CRLF pub fn from_bytes(buffer: &[u8]) -> Result { - // calculate length once - let len = buffer.len(); - // validate headers for this response type - if !(3..=1024).contains(&len) { - bail!("Unexpected header length") - } - if buffer - .get(..2) + use crate::Header; + let h = buffer.header_bytes()?; + if h.get(..2) .is_none_or(|c| c[0] != CODE[0] || c[1] != CODE[1]) { bail!("Invalid status code") } - // collect data bytes - let mut m = Vec::with_capacity(len); - for b in buffer[3..].iter() { - if *b == b'\r' { - continue; - } - if *b == b'\n' { - break; - } - m.push(*b) - } Ok(Self { - message: String::from_utf8(m).map(|m| if m.is_empty() { None } else { Some(m) })?, + message: String::from_utf8((&h[3..]).to_vec()).map(|m| { + if m.is_empty() { + None + } else { + Some(m) + } + })?, }) } diff --git a/src/response/failure/permanent/gone.rs b/src/response/failure/permanent/gone.rs index de24b62..dbbf1ea 100644 --- a/src/response/failure/permanent/gone.rs +++ b/src/response/failure/permanent/gone.rs @@ -11,31 +11,21 @@ impl Gone { /// Build `Self` from UTF-8 header bytes /// * expected buffer includes leading status code, message, CRLF pub fn from_bytes(buffer: &[u8]) -> Result { - // calculate length once - let len = buffer.len(); - // validate headers for this response type - if !(3..=1024).contains(&len) { - bail!("Unexpected header length") - } - if buffer - .get(..2) + use crate::Header; + let h = buffer.header_bytes()?; + if h.get(..2) .is_none_or(|c| c[0] != CODE[0] || c[1] != CODE[1]) { bail!("Invalid status code") } - // collect data bytes - let mut m = Vec::with_capacity(len); - for b in buffer[3..].iter() { - if *b == b'\r' { - continue; - } - if *b == b'\n' { - break; - } - m.push(*b) - } Ok(Self { - message: String::from_utf8(m).map(|m| if m.is_empty() { None } else { Some(m) })?, + message: String::from_utf8((&h[3..]).to_vec()).map(|m| { + if m.is_empty() { + None + } else { + Some(m) + } + })?, }) } diff --git a/src/response/failure/permanent/not_found.rs b/src/response/failure/permanent/not_found.rs index c9ada00..b547801 100644 --- a/src/response/failure/permanent/not_found.rs +++ b/src/response/failure/permanent/not_found.rs @@ -11,31 +11,21 @@ impl NotFound { /// Build `Self` from UTF-8 header bytes /// * expected buffer includes leading status code, message, CRLF pub fn from_bytes(buffer: &[u8]) -> Result { - // calculate length once - let len = buffer.len(); - // validate headers for this response type - if !(3..=1024).contains(&len) { - bail!("Unexpected header length") - } - if buffer - .get(..2) + use crate::Header; + let h = buffer.header_bytes()?; + if h.get(..2) .is_none_or(|c| c[0] != CODE[0] || c[1] != CODE[1]) { bail!("Invalid status code") } - // collect data bytes - let mut m = Vec::with_capacity(len); - for b in buffer[3..].iter() { - if *b == b'\r' { - continue; - } - if *b == b'\n' { - break; - } - m.push(*b) - } Ok(Self { - message: String::from_utf8(m).map(|m| if m.is_empty() { None } else { Some(m) })?, + message: String::from_utf8((&h[3..]).to_vec()).map(|m| { + if m.is_empty() { + None + } else { + Some(m) + } + })?, }) } diff --git a/src/response/failure/permanent/proxy_request_refused.rs b/src/response/failure/permanent/proxy_request_refused.rs index 477213e..efff8e4 100644 --- a/src/response/failure/permanent/proxy_request_refused.rs +++ b/src/response/failure/permanent/proxy_request_refused.rs @@ -11,31 +11,21 @@ impl ProxyRequestRefused { /// Build `Self` from UTF-8 header bytes /// * expected buffer includes leading status code, message, CRLF pub fn from_bytes(buffer: &[u8]) -> Result { - // calculate length once - let len = buffer.len(); - // validate headers for this response type - if !(3..=1024).contains(&len) { - bail!("Unexpected header length") - } - if buffer - .get(..2) + use crate::Header; + let h = buffer.header_bytes()?; + if h.get(..2) .is_none_or(|c| c[0] != CODE[0] || c[1] != CODE[1]) { bail!("Invalid status code") } - // collect data bytes - let mut m = Vec::with_capacity(len); - for b in buffer[3..].iter() { - if *b == b'\r' { - continue; - } - if *b == b'\n' { - break; - } - m.push(*b) - } Ok(Self { - message: String::from_utf8(m).map(|m| if m.is_empty() { None } else { Some(m) })?, + message: String::from_utf8((&h[3..]).to_vec()).map(|m| { + if m.is_empty() { + None + } else { + Some(m) + } + })?, }) } diff --git a/src/response/failure/temporary/cgi_error.rs b/src/response/failure/temporary/cgi_error.rs index de3e85e..00bf5d2 100644 --- a/src/response/failure/temporary/cgi_error.rs +++ b/src/response/failure/temporary/cgi_error.rs @@ -11,31 +11,21 @@ impl CgiError { /// Build `Self` from UTF-8 header bytes /// * expected buffer includes leading status code, message, CRLF pub fn from_bytes(buffer: &[u8]) -> Result { - // calculate length once - let len = buffer.len(); - // validate headers for this response type - if !(3..=1024).contains(&len) { - bail!("Unexpected header length") - } - if buffer - .get(..2) + use crate::Header; + let h = buffer.header_bytes()?; + if h.get(..2) .is_none_or(|c| c[0] != CODE[0] || c[1] != CODE[1]) { bail!("Invalid status code") } - // collect data bytes - let mut m = Vec::with_capacity(len); - for b in buffer[3..].iter() { - if *b == b'\r' { - continue; - } - if *b == b'\n' { - break; - } - m.push(*b) - } Ok(Self { - message: String::from_utf8(m).map(|m| if m.is_empty() { None } else { Some(m) })?, + message: String::from_utf8((&h[3..]).to_vec()).map(|m| { + if m.is_empty() { + None + } else { + Some(m) + } + })?, }) } diff --git a/src/response/failure/temporary/general.rs b/src/response/failure/temporary/general.rs index 36bf485..f6910c2 100644 --- a/src/response/failure/temporary/general.rs +++ b/src/response/failure/temporary/general.rs @@ -11,31 +11,21 @@ impl General { /// Build `Self` from UTF-8 header bytes /// * expected buffer includes leading status code, message, CRLF pub fn from_bytes(buffer: &[u8]) -> Result { - // calculate length once - let len = buffer.len(); - // validate headers for this response type - if !(3..=1024).contains(&len) { - bail!("Unexpected header length") - } - if buffer - .get(..2) + use crate::Header; + let h = buffer.header_bytes()?; + if h.get(..2) .is_none_or(|c| c[0] != CODE[0] || c[1] != CODE[1]) { bail!("Invalid status code") } - // collect data bytes - let mut m = Vec::with_capacity(len); - for b in buffer[3..].iter() { - if *b == b'\r' { - continue; - } - if *b == b'\n' { - break; - } - m.push(*b) - } Ok(Self { - message: String::from_utf8(m).map(|m| if m.is_empty() { None } else { Some(m) })?, + message: String::from_utf8((&h[3..]).to_vec()).map(|m| { + if m.is_empty() { + None + } else { + Some(m) + } + })?, }) } diff --git a/src/response/failure/temporary/proxy_error.rs b/src/response/failure/temporary/proxy_error.rs index 8bcf8a9..0b1d356 100644 --- a/src/response/failure/temporary/proxy_error.rs +++ b/src/response/failure/temporary/proxy_error.rs @@ -11,31 +11,21 @@ impl ProxyError { /// Build `Self` from UTF-8 header bytes /// * expected buffer includes leading status code, message, CRLF pub fn from_bytes(buffer: &[u8]) -> Result { - // calculate length once - let len = buffer.len(); - // validate headers for this response type - if !(3..=1024).contains(&len) { - bail!("Unexpected header length") - } - if buffer - .get(..2) + use crate::Header; + let h = buffer.header_bytes()?; + if h.get(..2) .is_none_or(|c| c[0] != CODE[0] || c[1] != CODE[1]) { bail!("Invalid status code") } - // collect data bytes - let mut m = Vec::with_capacity(len); - for b in buffer[3..].iter() { - if *b == b'\r' { - continue; - } - if *b == b'\n' { - break; - } - m.push(*b) - } Ok(Self { - message: String::from_utf8(m).map(|m| if m.is_empty() { None } else { Some(m) })?, + message: String::from_utf8((&h[3..]).to_vec()).map(|m| { + if m.is_empty() { + None + } else { + Some(m) + } + })?, }) } diff --git a/src/response/failure/temporary/server_unavailable.rs b/src/response/failure/temporary/server_unavailable.rs index 8fa09ab..11145b7 100644 --- a/src/response/failure/temporary/server_unavailable.rs +++ b/src/response/failure/temporary/server_unavailable.rs @@ -11,31 +11,21 @@ impl ServerUnavailable { /// Build `Self` from UTF-8 header bytes /// * expected buffer includes leading status code, message, CRLF pub fn from_bytes(buffer: &[u8]) -> Result { - // calculate length once - let len = buffer.len(); - // validate headers for this response type - if !(3..=1024).contains(&len) { - bail!("Unexpected header length") - } - if buffer - .get(..2) + use crate::Header; + let h = buffer.header_bytes()?; + if h.get(..2) .is_none_or(|c| c[0] != CODE[0] || c[1] != CODE[1]) { bail!("Invalid status code") } - // collect data bytes - let mut m = Vec::with_capacity(len); - for b in buffer[3..].iter() { - if *b == b'\r' { - continue; - } - if *b == b'\n' { - break; - } - m.push(*b) - } Ok(Self { - message: String::from_utf8(m).map(|m| if m.is_empty() { None } else { Some(m) })?, + message: String::from_utf8((&h[3..]).to_vec()).map(|m| { + if m.is_empty() { + None + } else { + Some(m) + } + })?, }) } diff --git a/src/response/failure/temporary/slow_down.rs b/src/response/failure/temporary/slow_down.rs index a8bf876..ca3497e 100644 --- a/src/response/failure/temporary/slow_down.rs +++ b/src/response/failure/temporary/slow_down.rs @@ -11,31 +11,21 @@ impl SlowDown { /// Build `Self` from UTF-8 header bytes /// * expected buffer includes leading status code, message, CRLF pub fn from_bytes(buffer: &[u8]) -> Result { - // calculate length once - let len = buffer.len(); - // validate headers for this response type - if !(3..=1024).contains(&len) { - bail!("Unexpected header length") - } - if buffer - .get(..2) + use crate::Header; + let h = buffer.header_bytes()?; + if h.get(..2) .is_none_or(|c| c[0] != CODE[0] || c[1] != CODE[1]) { bail!("Invalid status code") } - // collect data bytes - let mut m = Vec::with_capacity(len); - for b in buffer[3..].iter() { - if *b == b'\r' { - continue; - } - if *b == b'\n' { - break; - } - m.push(*b) - } Ok(Self { - message: String::from_utf8(m).map(|m| if m.is_empty() { None } else { Some(m) })?, + message: String::from_utf8((&h[3..]).to_vec()).map(|m| { + if m.is_empty() { + None + } else { + Some(m) + } + })?, }) } diff --git a/src/response/input/default.rs b/src/response/input/default.rs index c2181ea..014a3ce 100644 --- a/src/response/input/default.rs +++ b/src/response/input/default.rs @@ -11,31 +11,21 @@ impl Default { /// Build `Self` from UTF-8 header bytes /// * expected buffer includes leading status code, message, CRLF pub fn from_bytes(buffer: &[u8]) -> Result { - // calculate length once - let len = buffer.len(); - // validate headers for this response type - if !(3..=1024).contains(&len) { - bail!("Unexpected header length") - } - if buffer - .get(..2) + use crate::Header; + let h = buffer.header_bytes()?; + if h.get(..2) .is_none_or(|c| c[0] != CODE[0] || c[1] != CODE[1]) { bail!("Invalid status code") } - // collect data bytes - let mut m = Vec::with_capacity(len); - for b in buffer[3..].iter() { - if *b == b'\r' { - continue; - } - if *b == b'\n' { - break; - } - m.push(*b) - } Ok(Self { - message: String::from_utf8(m).map(|m| if m.is_empty() { None } else { Some(m) })?, + message: String::from_utf8((&h[3..]).to_vec()).map(|m| { + if m.is_empty() { + None + } else { + Some(m) + } + })?, }) } diff --git a/src/response/input/sensitive.rs b/src/response/input/sensitive.rs index 562bc82..0666c19 100644 --- a/src/response/input/sensitive.rs +++ b/src/response/input/sensitive.rs @@ -11,31 +11,21 @@ impl Sensitive { /// Build `Self` from UTF-8 header bytes /// * expected buffer includes leading status code, message, CRLF pub fn from_bytes(buffer: &[u8]) -> Result { - // calculate length once - let len = buffer.len(); - // validate headers for this response type - if !(3..=1024).contains(&len) { - bail!("Unexpected header length") - } - if buffer - .get(..2) + use crate::Header; + let h = buffer.header_bytes()?; + if h.get(..2) .is_none_or(|c| c[0] != CODE[0] || c[1] != CODE[1]) { bail!("Invalid status code") } - // collect data bytes - let mut m = Vec::with_capacity(len); - for b in buffer[3..].iter() { - if *b == b'\r' { - continue; - } - if *b == b'\n' { - break; - } - m.push(*b) - } Ok(Self { - message: String::from_utf8(m).map(|m| if m.is_empty() { None } else { Some(m) })?, + message: String::from_utf8((&h[3..]).to_vec()).map(|m| { + if m.is_empty() { + None + } else { + Some(m) + } + })?, }) } diff --git a/src/response/redirect/permanent.rs b/src/response/redirect/permanent.rs index 60cbaa0..9fe1a75 100644 --- a/src/response/redirect/permanent.rs +++ b/src/response/redirect/permanent.rs @@ -11,35 +11,18 @@ impl Permanent { /// Build `Self` from UTF-8 header bytes /// * expected buffer includes leading status code, message, CRLF pub fn from_bytes(buffer: &[u8]) -> Result { - // calculate length once - let len = buffer.len(); - // validate headers for this response type - if !(3..=1024).contains(&len) { - bail!("Unexpected header length") - } - if buffer - .get(..2) + use crate::Header; + let h = buffer.header_bytes()?; + if h.get(..2) .is_none_or(|c| c[0] != CODE[0] || c[1] != CODE[1]) { bail!("Invalid status code") } - // collect data bytes - let mut t = Vec::with_capacity(len); - for b in buffer[3..].iter() { - if *b == b'\r' { - continue; - } - if *b == b'\n' { - break; - } - t.push(*b) - } - Ok(Self { - target: if t.is_empty() { + target: if h.is_empty() { bail!("Target required") } else { - String::from_utf8(t)? + String::from_utf8((&h[3..]).to_vec())? }, }) } diff --git a/src/response/redirect/temporary.rs b/src/response/redirect/temporary.rs index 25e3326..972d4ab 100644 --- a/src/response/redirect/temporary.rs +++ b/src/response/redirect/temporary.rs @@ -11,35 +11,18 @@ impl Temporary { /// Build `Self` from UTF-8 header bytes /// * expected buffer includes leading status code, message, CRLF pub fn from_bytes(buffer: &[u8]) -> Result { - // calculate length once - let len = buffer.len(); - // validate headers for this response type - if !(3..=1024).contains(&len) { - bail!("Unexpected header length") - } - if buffer - .get(..2) + use crate::Header; + let h = buffer.header_bytes()?; + if h.get(..2) .is_none_or(|c| c[0] != CODE[0] || c[1] != CODE[1]) { bail!("Invalid status code") } - // collect data bytes - let mut t = Vec::with_capacity(len); - for b in buffer[3..].iter() { - if *b == b'\r' { - continue; - } - if *b == b'\n' { - break; - } - t.push(*b) - } - Ok(Self { - target: if t.is_empty() { + target: if h.is_empty() { bail!("Target required") } else { - String::from_utf8(t)? + String::from_utf8((&h[3..]).to_vec())? }, }) }