mirror of
https://github.com/YGGverse/titanite.git
synced 2026-03-31 09:05:31 +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};
|
use anyhow::{bail, Result};
|
||||||
|
|
||||||
|
/// https://geminiprotocol.net/docs/protocol-specification.gmi#requests
|
||||||
pub enum Request<'a> {
|
pub enum Request<'a> {
|
||||||
Gemini(Gemini),
|
Gemini(Gemini),
|
||||||
Titan(Titan<'a>),
|
Titan(Titan<'a>),
|
||||||
|
|
@ -22,7 +23,6 @@ impl<'a> Request<'a> {
|
||||||
None => bail!("Empty request"),
|
None => bail!("Empty request"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_bytes(self) -> Vec<u8> {
|
pub fn into_bytes(self) -> Vec<u8> {
|
||||||
match self {
|
match self {
|
||||||
Self::Gemini(this) => this.into_bytes(),
|
Self::Gemini(this) => this.into_bytes(),
|
||||||
|
|
|
||||||
|
|
@ -7,24 +7,34 @@ pub struct Gemini {
|
||||||
|
|
||||||
impl Gemini {
|
impl Gemini {
|
||||||
pub fn from_bytes(buffer: &[u8]) -> Result<Self> {
|
pub fn from_bytes(buffer: &[u8]) -> Result<Self> {
|
||||||
let mut l: usize = 0;
|
if buffer.len() > 1024 {
|
||||||
for b in buffer {
|
bail!("Header bytes length reached")
|
||||||
l += 1;
|
}
|
||||||
if l > 1024 {
|
match buffer.iter().position(|&b| b == b'\r') {
|
||||||
bail!("Max header length reached!")
|
Some(n) => {
|
||||||
}
|
if buffer.get(n + 1).is_some_and(|&b| b == b'\n') {
|
||||||
if *b == b'\r' {
|
Ok(Self {
|
||||||
continue;
|
url: String::from_utf8(buffer[..n].to_vec())?,
|
||||||
}
|
})
|
||||||
if *b == b'\n' {
|
} else {
|
||||||
break;
|
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> {
|
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