mirror of
https://github.com/YGGverse/titanite.git
synced 2026-03-31 17:15:33 +00:00
fix gemini request parser, implement tests
This commit is contained in:
parent
fa11659af0
commit
d0fdbf6ac4
2 changed files with 27 additions and 17 deletions
|
|
@ -6,6 +6,7 @@ pub use titan::Titan;
|
|||
|
||||
use anyhow::{bail, Result};
|
||||
|
||||
/// https://geminiprotocol.net/docs/protocol-specification.gmi#requests
|
||||
pub enum Request<'a> {
|
||||
Gemini(Gemini),
|
||||
Titan(Titan<'a>),
|
||||
|
|
@ -22,7 +23,6 @@ impl<'a> Request<'a> {
|
|||
None => bail!("Empty request"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_bytes(self) -> Vec<u8> {
|
||||
match self {
|
||||
Self::Gemini(this) => this.into_bytes(),
|
||||
|
|
|
|||
|
|
@ -7,24 +7,34 @@ pub struct Gemini {
|
|||
|
||||
impl Gemini {
|
||||
pub fn from_bytes(buffer: &[u8]) -> Result<Self> {
|
||||
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;
|
||||
}
|
||||
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(buffer[..l].to_vec())?,
|
||||
})
|
||||
}
|
||||
pub fn into_bytes(self) -> Vec<u8> {
|
||||
self.url.to_string().into_bytes()
|
||||
let mut bytes = Vec::with_capacity(self.url.len() + 2);
|
||||
bytes.extend(self.url.into_bytes());
|
||||
bytes.extend(b"\r\n");
|
||||
bytes
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
const REQUEST: &[u8] = "gemini://geminiprotocol.net\r\n".as_bytes();
|
||||
let request = Gemini::from_bytes(REQUEST).unwrap();
|
||||
assert_eq!(request.url, "gemini://geminiprotocol.net");
|
||||
assert_eq!(request.into_bytes(), REQUEST);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue