Skip to content
Snippets Groups Projects
Commit 9e291184 authored by codecraft's avatar codecraft :crocodile:
Browse files

New Documentation and changing Request mime type to (Mime, String) for

the whole data of the content-type
parent 901adb2c
No related branches found
No related tags found
1 merge request!1Initial feature merge
......@@ -26,13 +26,20 @@ impl FromRequest for Vec<u8> {
type HeaderMap = Vec<String>;
/// A struct to handle Requests
///
#[derive(Clone)]
pub struct Request<'a> {
/// The requested Uri
pub uri: Uri<'a>,
/// All headers of the request that haven't been parsed
pub headers: HeaderMap,
/// The methods Request represented with the [Method]
pub method: Method,
/// An optional HashMap representation of all Cookies of the request
pub cookies: Option<HashMap<String, String>>,
pub mime_type: Option<Mime>,
/// If the has a body it represents the [Mime]-type of the body
pub mime_type: Option<(Mime, String)>,
// pub connection: ConnectionMeta,
}
......
......@@ -6,6 +6,55 @@ use super::{datatypes::ParseErrors, ParseFormError, Request};
static TWO_NEWLINES: u8 = 3;
impl Request<'_> {
/// # Gets data from a get_form as a HashMap
///
/// # Errors
/// Gives back a [ParseFormError], top level, if there is lacking data
///
/// If everything is fine on the top level it gives back a HashMap of keys and Results, that
/// indicate wether the key exists with the [ParseFormError] with an error of
/// [ParseErrors::NoData] or wether the key is corrupt with the [ParseErrors::BadData]-Variant
///
/// # Examples
/// ```
/// let request = Request {
/// uri: "/form?name=Name&age=Age",
/// headers: vec![],
/// method: Method::Get,
/// cookies: None,
/// mime_type: None,
/// };
/// let right = request.get_get_form_keys(&["name", "age"]).unwrap();
/// assert_eq!(&"Name", right.get("name").unwrap().as_ref().unwrap());
/// assert_eq!(&"Age", right.get("age").unwrap().as_ref().unwrap());
///
/// let wrong_request = Request {
/// uri: "/form",
/// ..request.clone()
/// };
/// assert_eq!(
/// Err(ParseFormError {
/// error: ParseErrors::NoData
/// }),
/// wrong_request.get_get_form_keys(&["name", "age"])
/// );
///
/// let bad_data = Request {
/// uri: "/form?age=",
/// ..request.clone()
/// };
/// let wrong = bad_data.get_get_form_keys(&["name", "age"]).unwrap();
/// assert_eq!(
/// &Err(ParseFormError {
/// error: ParseErrors::NoData
/// }),
/// wrong.get("name").unwrap()
/// );
/// assert_eq!(&Ok(""), wrong.get("age").unwrap());
/// ```
///
/// # Panics
/// No Panics
pub fn get_get_form_keys<'a>(
&'a self,
keys: &'a [&str],
......@@ -59,11 +108,11 @@ impl Request<'_> {
error: ParseErrors::NoData,
}));
}
let Some(mime_type) = self.mime_type else {
let Some(ref mime_type) = self.mime_type else {
return Err(ParseFormError { error: ParseErrors::BadData });
};
match mime_type {
match mime_type.0 {
Mime::ApplicationXWwwFormUrlencoded => {
let Ok(data) = String::from_utf8(data.to_vec()) else {
return Err(ParseFormError { error: ParseErrors::BadData });
......@@ -82,15 +131,7 @@ impl Request<'_> {
}
}
Mime::MultipartFormData => {
let Some(post_type) = self
.headers
.iter()
.find(|header| header.contains("Content-Type: ")) else {
return Err(ParseFormError { error: ParseErrors::BadData });
};
let content_type = post_type.trim().strip_prefix("Content-Type: ").unwrap();
let Some(mut boundary) = content_type.split(';').find(|element| element.trim().starts_with("boundary=")) else {
let Some(mut boundary) = mime_type.1.split(';').find(|element| element.trim().starts_with("boundary=")) else {
return Err(ParseFormError { error: ParseErrors::BadData });
};
boundary = boundary
......@@ -187,20 +228,61 @@ impl Request<'_> {
#[cfg(test)]
mod test {
use crate::{
handling::routes::Data,
handling::{
methods::Method,
request::{datatypes::ParseErrors, ParseFormError},
routes::Data,
},
utils::mime::mime_enum::Mime::{ApplicationXWwwFormUrlencoded, MultipartFormData},
};
use super::Request;
#[test]
fn try_get_test() {
let request = Request {
uri: "/form?name=Name&age=Age",
headers: vec![],
method: Method::Get,
cookies: None,
mime_type: None,
};
let right = request.get_get_form_keys(&["name", "age"]).unwrap();
assert_eq!(&"Name", right.get("name").unwrap().as_ref().unwrap());
assert_eq!(&"Age", right.get("age").unwrap().as_ref().unwrap());
let wrong_request = Request {
uri: "/form",
..request.clone()
};
assert_eq!(
Err(ParseFormError {
error: ParseErrors::NoData
}),
wrong_request.get_get_form_keys(&["name", "age"])
);
let bad_data = Request {
uri: "/form?age=",
..request.clone()
};
let wrong = bad_data.get_get_form_keys(&["name", "age"]).unwrap();
assert_eq!(
&Err(ParseFormError {
error: ParseErrors::NoData
}),
wrong.get("name").unwrap()
);
assert_eq!(&Ok(""), wrong.get("age").unwrap());
}
#[test]
fn try_post_text() {
let req = Request {
uri: "",
headers: vec!["Content-Type: application/x-www-form-urlencoded".to_string()],
method: crate::handling::methods::Method::Post,
method: Method::Post,
cookies: None,
mime_type: Some(ApplicationXWwwFormUrlencoded),
mime_type: Some((ApplicationXWwwFormUrlencoded, "".into())),
};
let data = Data {
buffer: b"message=23&message1=24".to_vec(),
......@@ -218,9 +300,12 @@ mod test {
let req = Request {
uri: "",
headers: vec!["Content-Type: multipart/form-data; boundary=\"boundary\"".to_string()],
method: crate::handling::methods::Method::Post,
method: Method::Post,
cookies: None,
mime_type: Some(MultipartFormData),
mime_type: Some((
MultipartFormData,
"charset=UTF-8; boundary=\"boundary\"".into(),
)),
};
let data = Data {
buffer: b"--boundary\r
......
use super::datatypes::Request;
impl Request<'_> {
impl<'a> Request<'a> {
/// Sets the `mime_type` of this [`Request`] from the headers.
///
/// The mime_type can remain none if there isn't a `Content-Type: ` header
......@@ -17,7 +17,7 @@ impl Request<'_> {
/// headers: vec![
/// "GET / 23".to_string(),
/// "SDF:LKJSD:F".to_string(),
/// "Content-Type: text/plain".to_string(),
/// "Content-Type: text/plain; charset=UTF-8".to_string(),
/// "SDF".to_string(),
/// ],
/// method: Method::Get,
......@@ -38,7 +38,7 @@ impl Request<'_> {
/// request.mime_from_headers();
/// wrong.mime_from_headers();
/// assert_eq!(None, wrong.mime_type);
/// assert_eq!(Mime::TextPlain, request.mime_type.unwrap());
/// assert_eq!((Mime::TextPlain, " charset=UTF-8".to_string()), request.mime_type.unwrap());
/// ```
/// # Panics
/// No Panics
......@@ -48,14 +48,21 @@ impl Request<'_> {
.find(|header| header.starts_with("Content-Type: ")) else {
return;
};
let content_type_string = content_type_header
let content_type_string: &str = content_type_header
.strip_prefix("Content-Type: ")
.unwrap()
.to_string();
.trim();
self.mime_type = match content_type_string.split_once(';') {
Some(sub) => sub.0.trim().parse().ok(),
None => content_type_string.trim().parse().ok(),
self.mime_type = if let Some(content_type) = content_type_string.split_once(';') {
let Ok(mime) = content_type.0.trim().parse() else {
return;
};
Some((mime, content_type.1.to_owned()))
} else {
let Ok(mime) = content_type_string.parse() else {
return;
};
Some((mime, "".to_owned()))
};
}
}
......@@ -96,6 +103,6 @@ mod test {
request.mime_from_headers();
wrong.mime_from_headers();
assert_eq!(None, wrong.mime_type);
assert_eq!(Mime::TextPlain, request.mime_type.unwrap());
assert_eq!((Mime::TextPlain, "".to_owned()), request.mime_type.unwrap());
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment