diff --git a/core/http/src/handling/request.rs b/core/http/src/handling/request.rs index adfb6b82dbc82fc647d2cdcfcd5f44502ee2a290..b3615f15db22cc3a11631ad7ce585274ccdae22c 100644 --- a/core/http/src/handling/request.rs +++ b/core/http/src/handling/request.rs @@ -1,6 +1,11 @@ // use std::net::SocketAddr; -use super::{methods::Method, routes::Uri}; +use std::{collections::HashMap, error::Error, fmt::Display}; + +use super::{ + methods::Method, + routes::{Data, Uri}, +}; type HeaderMap = Vec<String>; #[derive(Clone)] @@ -23,6 +28,34 @@ pub enum MediaType { Html, } +#[derive(Debug)] +pub enum ParseErrors { + NoData, + BadData, +} + +#[derive(Debug)] +pub struct ParseFormError { + pub error: ParseErrors, +} + +impl Display for ParseFormError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.error) + } +} + +impl Display for ParseErrors { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ParseErrors::NoData => write!(f, "No Data at key"), + ParseErrors::BadData => write!(f, "Bad Data at key"), + } + } +} + +impl Error for ParseFormError {} + impl Request<'_> { pub fn can_have_body(&self) -> bool { match self.method { @@ -30,4 +63,45 @@ impl Request<'_> { _ => false, } } + pub fn get_form_keys(&self, keys: Vec<&str>) -> Result<HashMap<&str, &str>, ParseFormError> { + let data = self.uri.split_once("?"); + if data == None { + return Err(ParseFormError { + error: ParseErrors::NoData, + }); + } + let data = data + .unwrap() + .1 + .split("&") + .map(|kvp| kvp.split_once("=")) + .collect::<Vec<Option<(&str, &str)>>>(); + + let mut values: HashMap<&str, &str> = HashMap::new(); + for kvp in data { + if kvp == None { + continue; + } + let kvp = kvp.unwrap(); + values.insert(kvp.0, kvp.1); + } + let mut response = HashMap::new(); + for key in keys { + let entry = values.get_key_value(key); + if entry == None { + return Err(ParseFormError { + error: ParseErrors::NoData, + }); + } + response.insert(*entry.unwrap().0, *entry.unwrap().1); + } + Ok(response) + } + pub fn get_form_keys_with_data( + &self, + _keys: Vec<&str>, + _data_buffer: Data, + ) -> Result<HashMap<&str, &str>, ParseFormError> { + todo!() + } } diff --git a/core/http/src/handling/routes.rs b/core/http/src/handling/routes.rs index 3d8b405d96dfa14760396a543b6543a80e4f9a65..795e760f90cd3a64934e1e222b301f1afee9a031 100644 --- a/core/http/src/handling/routes.rs +++ b/core/http/src/handling/routes.rs @@ -43,7 +43,9 @@ impl Route<'_> { } else { return false; }; - if true_str.starts_with("<") && true_str.ends_with("..>") { + if (true_str.starts_with("<") && true_str.ends_with("..>")) + || (comp_str.starts_with(true_str) && comp_str.contains("?")) + { return true; } if true_str.starts_with("<") && true_str.ends_with(">") { diff --git a/site/src/main.rs b/site/src/main.rs index e58195ab7eea5eaa9a5ed37016e07f18f73d9550..22897e249dc9114d5d0a239d9f281bdf663dee8f 100644 --- a/site/src/main.rs +++ b/site/src/main.rs @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::{path::PathBuf, collections::HashMap}; use http::handling::{ file_handlers::NamedFile, @@ -8,12 +8,26 @@ use http::handling::{ routes::{Data, Route}, }; -fn handle_static_hi(request: Request<'_>, data: Data) -> Outcome<Response, Status, Data> { - // Outcome::Success(Response { headers: vec![ - // format!("Content-Length: 4"), - // format!("Content-Type: text/plain") - // ], status: Some(Status::Ok), body: Box::new("jkl;") }) - Outcome::Forward(data) +fn hashmap_to_string(map: &HashMap<&str, &str>) -> String { + let mut result = String::new(); + for (key, value) in map { + result.push_str(key); + result.push('='); + result.push_str(value); + result.push(';'); + } + result.pop(); // Remove the trailing semicolon if desired + result +} + + +fn handle_static_hi(request: Request<'_>, _data: Data) -> Outcome<Response, Status, Data> { + let response = hashmap_to_string(&request.get_form_keys(vec!["asdf", "jkj"]).unwrap()); + Outcome::Success(Response { headers: vec![ + format!("Content-Length: {}", response.len()), + format!("Content-Type: text/plain") + ], status: Some(Status::Ok), body: Box::new(response) }) + // Outcome::Forward(data) }