diff --git a/src/main.rs b/src/main.rs index 7281154..a961913 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,17 +1,10 @@ // #![feature(if_let_guard)] -use std::{ io::{ BufRead, BufReader, Write }, net::TcpListener }; +use std::{ collections::HashMap, io::{ BufRead, BufReader, Write }, net::TcpListener }; use anyhow::Result; -use thiserror::Error; -macro_rules! d { () => { Default::default() }; } -macro_rules! f { ($s: expr) => { format!($s) }; } - -#[derive(Clone, Debug, Error)] -enum E { - #[error("Invalid request data found during parsing")] - InvalidRequest, -} +mod utils; +use utils::*; fn main() -> Result<()> { let listener = TcpListener::bind("127.0.0.1:4221").unwrap(); @@ -36,10 +29,14 @@ fn main() -> Result<()> { (method, path, ver) }; - let response = match path.as_str() { - "/" => Response::Empty, + let headers = Headers::parse(data); + + + let response = match path.trim_start_matches("/") { + "" => Response::Empty, + "user-agent" => Response::TextPlain(headers.get("User-Agent")), // p if let Some(echo) = p.strip_prefix("/echo/") => Response::TextPlain(echo), // a nicer way to do that, not available in stable yet - p if p.starts_with("/echo/") => Response::TextPlain(p.trim_start_matches("/echo/")), + p if p.starts_with("echo/") => Response::TextPlain(p.trim_start_matches("echo/")), _ => Response::_404, }; @@ -58,6 +55,25 @@ fn main() -> Result<()> { Ok(()) } + +pub struct Headers (HashMap); + +impl Headers { + pub fn parse (lines: impl Iterator) -> Self { + Self(HashMap::from_iter(lines.filter_map(|line| + line.split_once(":") + .map(|(a, b)| ( + a.trim().to_lowercase(), + b.trim().to_owned() + )) + ))) + } + + pub fn get <'a> (&'a self, key: &str) -> &'a str { + self.0.get(&key.to_lowercase()).map(|e| e.as_str()).unwrap_or_default() + } +} + #[derive(Debug, Clone)] enum Response <'a> { _404, diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..31ba577 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,12 @@ +use thiserror::Error; + +#[macro_export] +macro_rules! d { () => { Default::default() }; } +#[macro_export] +macro_rules! f { ($s: expr) => { format!($s) }; } + +#[derive(Clone, Debug, Error)] +pub enum E { + #[error("Invalid request data found during parsing")] + InvalidRequest, +}