diff --git a/src/request.rs b/src/request.rs index a59f68f..4cf75de 100644 --- a/src/request.rs +++ b/src/request.rs @@ -4,6 +4,8 @@ pub mod titan; pub use gemini::Gemini; pub use titan::Titan; +pub const HEADER_MAX_LEN: usize = 1024; + use anyhow::{bail, Result}; /// https://geminiprotocol.net/docs/protocol-specification.gmi#requests @@ -30,3 +32,19 @@ impl<'a> Request<'a> { } } } + +pub fn header_bytes(buffer: &[u8]) -> Result<&[u8]> { + match buffer.iter().position(|&b| b == b'\r') { + Some(n) => { + if n > HEADER_MAX_LEN { + bail!("Header bytes length reached") + } + if buffer.get(n + 1).is_some_and(|&b| b == b'\n') { + Ok(&buffer[..n]) + } else { + bail!("LF byte not found") + } + } + None => bail!("CR byte not found"), + } +} diff --git a/src/request/gemini.rs b/src/request/gemini.rs index 4bc7c84..e9568e2 100644 --- a/src/request/gemini.rs +++ b/src/request/gemini.rs @@ -1,4 +1,4 @@ -use anyhow::{bail, Result}; +use anyhow::Result; /// [Gemini](https://geminiprotocol.net/docs/protocol-specification.gmi) request pub struct Gemini { @@ -7,21 +7,9 @@ pub struct Gemini { impl Gemini { pub fn from_bytes(buffer: &[u8]) -> Result { - if buffer.len() > 1024 { - bail!("Header bytes length reached") - } - match buffer.iter().position(|&b| b == b'\r') { - Some(n) => { - if buffer.get(n + 1).is_some_and(|&b| b == b'\n') { - Ok(Self { - url: String::from_utf8(buffer[..n].to_vec())?, - }) - } else { - bail!("LF byte not found") - } - } - None => bail!("CR byte not found"), - } + Ok(Self { + url: String::from_utf8(crate::request::header_bytes(buffer)?.to_vec())?, + }) } pub fn into_bytes(self) -> Vec { let mut bytes = Vec::with_capacity(self.url.len() + 2);