From 29bec6fc8f7380dda275cae4e02e91cf040a970a Mon Sep 17 00:00:00 2001
From: Darius Auding <Darius.auding@gmx.de>
Date: Sat, 24 Jun 2023 13:27:50 +0200
Subject: [PATCH] Refactoring the Request struct into it's own seperated module
 with seprate impl's, fixing some code, ...

---
 .../src/handlers/{handlers.rs => handler.rs}  |  13 +-
 core/http/src/handlers/mod.rs                 |   2 +-
 core/http/src/handling/request/cookies.rs     |  52 ++--
 core/http/src/handling/request/datatypes.rs   |   6 +-
 core/http/src/handling/request/form_utils.rs  | 250 ++++++++++++++++
 core/http/src/handling/request/mod.rs         |   3 +-
 .../http/src/handling/request/request_impl.rs | 282 +-----------------
 .../http/src/handling/request/request_mime.rs |  59 ++++
 core/http/src/setup.rs                        |   4 +-
 site/src/main.rs                              |   1 +
 10 files changed, 355 insertions(+), 317 deletions(-)
 rename core/http/src/handlers/{handlers.rs => handler.rs} (96%)
 mode change 100755 => 100644
 create mode 100644 core/http/src/handling/request/form_utils.rs
 create mode 100644 core/http/src/handling/request/request_mime.rs
 mode change 100755 => 100644 core/http/src/setup.rs

diff --git a/core/http/src/handlers/handlers.rs b/core/http/src/handlers/handler.rs
old mode 100755
new mode 100644
similarity index 96%
rename from core/http/src/handlers/handlers.rs
rename to core/http/src/handlers/handler.rs
index 32376bc..67d5117
--- a/core/http/src/handlers/handlers.rs
+++ b/core/http/src/handlers/handler.rs
@@ -4,7 +4,7 @@ use tokio::{io::{AsyncReadExt, BufReader, AsyncBufReadExt, AsyncWriteExt}, net::
 
 use crate::handling::{
     file_handlers::NamedFile,
-    request::{Request, extract_cookies_from_vec},
+    request::Request,
     response::{Outcome, Response, ResponseBody, Status},
     routes::Data, methods::Method,
 };
@@ -26,7 +26,6 @@ pub async fn handle_connection(mut stream: TcpStream, mountpoints: Vec<MountPoin
         }
         http_request.push(buffer);
     }
-    println!("{:?}", http_request);
 
     let request_status_line = if let Some(status_line) = http_request.get(0).cloned() {
         status_line
@@ -35,15 +34,16 @@ pub async fn handle_connection(mut stream: TcpStream, mountpoints: Vec<MountPoin
         return;
     };
 
-    let request = Request {
+    let mut request = Request {
         uri: if let Some(uri) = &request_status_line.split(" ").nth(1) {
             *uri
         } else {
             eprintln!("\x1b[31mAborting due to invalid status line\x1b[0m");
             return;
         },
-        cookies: extract_cookies_from_vec(&mut http_request),
+        cookies: Request::extract_cookies_from_vec(&mut http_request),
         headers: http_request,
+        mime_type: None,
         method: if let Some(method) = request_status_line
             .split(" ")
             .next() {
@@ -90,6 +90,7 @@ pub async fn handle_connection(mut stream: TcpStream, mountpoints: Vec<MountPoin
             0
         };
         if length != 0 {
+            request.mime_type = Request::extract_mime_from_vec(&mut request.headers);
             let mut buffer = vec![0u8; MAX_HTTP_MESSAGE_SIZE.into()];
             let read = buf_reader.read(&mut buffer).await.unwrap();
             if read != length {
@@ -152,9 +153,7 @@ pub async fn handle_connection(mut stream: TcpStream, mountpoints: Vec<MountPoin
     resp.extend_from_slice(&response.1);
     if let Err(e) = stream.write_all(&resp).await {
         eprintln!("\x1b[31mError {e} occured when trying to write answer to TCP-Stream for Client, aborting\x1b[0m");
-        return;
-    }
-    return;
+    } 
 }
 
 fn failure_handler(status: Status) -> (String, Vec<u8>) {
diff --git a/core/http/src/handlers/mod.rs b/core/http/src/handlers/mod.rs
index c3d4495..062ae9d 100644
--- a/core/http/src/handlers/mod.rs
+++ b/core/http/src/handlers/mod.rs
@@ -1 +1 @@
-pub mod handlers;
+pub mod handler;
diff --git a/core/http/src/handling/request/cookies.rs b/core/http/src/handling/request/cookies.rs
index c11bd45..d078c76 100644
--- a/core/http/src/handling/request/cookies.rs
+++ b/core/http/src/handling/request/cookies.rs
@@ -1,34 +1,38 @@
 use std::collections::HashMap;
 
-pub fn extract_cookies_from_vec(headers: &mut Vec<String>) -> Option<HashMap<String, String>> {
-    let mut cookies: HashMap<String, String> = HashMap::new();
-    let mut cookies_string = if let Some(index) = headers
-        .iter()
-        .position(|header| header.starts_with("Cookie: "))
-    {
-        headers.remove(index)
-    } else {
-        return None;
-    };
-    cookies_string = cookies_string
-        .strip_prefix("Cookie: ")
-        .unwrap()
-        .trim()
-        .to_string();
-    for cookie in cookies_string.split(';') {
-        let Some((name, cookie)) = cookie.split_once('=') else {
+use super::Request;
+
+impl Request<'_> {
+    pub fn extract_cookies_from_vec(headers: &mut Vec<String>) -> Option<HashMap<String, String>> {
+        let mut cookies: HashMap<String, String> = HashMap::new();
+        let mut cookies_string = if let Some(index) = headers
+            .iter()
+            .position(|header| header.starts_with("Cookie: "))
+        {
+            headers.remove(index)
+        } else {
             return None;
         };
-        cookies
-            .entry(name.trim().to_string())
-            .or_insert(cookie.trim().to_string());
+        cookies_string = cookies_string
+            .strip_prefix("Cookie: ")
+            .unwrap()
+            .trim()
+            .to_string();
+        for cookie in cookies_string.split(';') {
+            let Some((name, cookie)) = cookie.split_once('=') else {
+                return None;
+            };
+            cookies
+                .entry(name.trim().to_string())
+                .or_insert(cookie.trim().to_string());
+        }
+        Some(cookies)
     }
-    Some(cookies)
 }
 
 #[cfg(test)]
 mod test {
-    use crate::handling::request::extract_cookies_from_vec;
+    use crate::handling::request::Request;
 
     #[test]
     fn test_cookies() {
@@ -46,8 +50,8 @@ mod test {
 
         let mut wrong = vec!["GET / HTTP/1.1".to_string()];
 
-        assert_eq!(None, extract_cookies_from_vec(&mut wrong));
-        let cookies = extract_cookies_from_vec(&mut request_vec);
+        assert_eq!(None, Request::extract_cookies_from_vec(&mut wrong));
+        let cookies = Request::extract_cookies_from_vec(&mut request_vec);
         assert_eq!(right_finished_vec, request_vec);
         assert_eq!("23", cookies.clone().unwrap().get("io").unwrap());
         assert_eq!("as", cookies.unwrap().get("f").unwrap());
diff --git a/core/http/src/handling/request/datatypes.rs b/core/http/src/handling/request/datatypes.rs
index 68e32d5..6b72da9 100644
--- a/core/http/src/handling/request/datatypes.rs
+++ b/core/http/src/handling/request/datatypes.rs
@@ -1,6 +1,9 @@
 use std::{collections::HashMap, error::Error, fmt::Display};
 
-use crate::handling::{methods::Method, routes::Uri};
+use crate::{
+    handling::{methods::Method, routes::Uri},
+    utils::mime::mime_enum::Mime,
+};
 
 pub trait FromRequest: Send {
     fn get_data(&self) -> &Self;
@@ -29,6 +32,7 @@ pub struct Request<'a> {
     pub headers: HeaderMap,
     pub method: Method,
     pub cookies: Option<HashMap<String, String>>,
+    pub mime_type: Option<Mime>,
     // pub connection: ConnectionMeta,
 }
 
diff --git a/core/http/src/handling/request/form_utils.rs b/core/http/src/handling/request/form_utils.rs
new file mode 100644
index 0000000..fef8a4f
--- /dev/null
+++ b/core/http/src/handling/request/form_utils.rs
@@ -0,0 +1,250 @@
+use std::collections::HashMap;
+
+use crate::{handling::routes::Data, utils::mime::mime_enum::Mime};
+
+use super::{datatypes::ParseErrors, ParseFormError, Request};
+static TWO_NEWLINES: u8 = 3;
+
+impl Request<'_> {
+    pub fn get_get_form_keys<'a>(
+        &'a self,
+        keys: &'a [&str],
+    ) -> Result<HashMap<&str, Result<&str, ParseFormError>>, ParseFormError> {
+        let data = if let Some(val) = self.uri.split_once('?') {
+            val
+        } else {
+            return Err(ParseFormError {
+                error: ParseErrors::NoData,
+            });
+        };
+        let data = data
+            .1
+            .split("&")
+            .map(|kvp| kvp.split_once("="))
+            .collect::<Vec<Option<(&str, &str)>>>();
+
+        let mut values: HashMap<&str, &str> = HashMap::new();
+        for kvp in data {
+            let kvp = if let Some(kvp) = kvp {
+                kvp
+            } else {
+                continue;
+            };
+            values.insert(kvp.0, kvp.1);
+        }
+        let mut response = HashMap::new();
+        for key in keys {
+            let entry = if let Some(val) = values.get(key) {
+                Ok(*val)
+            } else {
+                Err(ParseFormError {
+                    error: ParseErrors::NoData,
+                })
+            };
+            response.insert((*key).into(), entry);
+        }
+        Ok(response)
+    }
+    pub fn get_post_data<'a>(
+        &'a self,
+        keys: &[&'a str],
+        data: &Data,
+    ) -> Result<HashMap<String, Result<Vec<u8>, ParseFormError>>, ParseFormError> {
+        let data = data.buffer.as_slice();
+        let mut keymap: HashMap<String, Result<Vec<u8>, ParseFormError>> =
+            HashMap::with_capacity(keys.len());
+
+        for key in keys {
+            keymap.entry(key.to_string()).or_insert(Err(ParseFormError {
+                error: ParseErrors::NoData,
+            }));
+        }
+        let Some(mime_type) = self.mime_type else {
+            return Err(ParseFormError { error: ParseErrors::BadData });
+        };
+
+        match mime_type {
+            Mime::ApplicationXWwwFormUrlencoded => {
+                let Ok(data) = String::from_utf8(data.to_vec()) else {
+                    return Err(ParseFormError { error: ParseErrors::BadData });
+                };
+                for kvp in data.split('&') {
+                    let Some(mut kvp) = kvp.split_once('=') else {
+                        return Err(ParseFormError { error: ParseErrors::BadData });
+                    };
+
+                    let Some(thing) = keymap.get_mut(kvp.0) else {
+                        continue;
+                    };
+                    kvp.1 = kvp.1.trim_end_matches('\0');
+
+                    *thing = Ok(kvp.1.as_bytes().to_vec());
+                }
+            }
+            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 {
+                    return Err(ParseFormError { error: ParseErrors::BadData });
+                };
+                boundary = boundary
+                    .trim()
+                    .strip_prefix("boundary=")
+                    .unwrap()
+                    .trim_matches('"');
+                let mut temp_bound = "--".to_string();
+                temp_bound.push_str(&format!("{boundary}"));
+                let end_boundary = format!("{temp_bound}--\r").as_bytes().to_owned();
+                temp_bound.push('\r');
+                let boundary = temp_bound.as_bytes();
+                Self::get_multipart_data(data, boundary, &end_boundary, &mut keymap);
+            }
+            _ => {
+                return Err(ParseFormError {
+                    error: ParseErrors::BadData,
+                })
+            }
+        };
+        Ok(keymap)
+    }
+    fn get_multipart_data(
+        data: &[u8],
+        boundary: &[u8],
+        end_boundary: &[u8],
+        map: &mut HashMap<String, Result<Vec<u8>, ParseFormError>>,
+    ) {
+        let mut current_part: Vec<&[u8]> = vec![];
+        let mut current_key: Option<String> = None;
+        let mut ignore_line = 0;
+        for part in data.split(|byte| byte == &b'\n') {
+            if part == &[b'\r'] {
+                if let Some(_) = current_key {
+                    if ignore_line >= TWO_NEWLINES {
+                        current_part.push(&[b'\n']);
+                        continue;
+                    }
+                    ignore_line += 1;
+                }
+                continue;
+            }
+            if part == end_boundary {
+                if let Some(key) = &current_key {
+                    let mut part = current_part.join(&b'\n');
+                    if part.ends_with(&[b'\r']) {
+                        part.pop();
+                    }
+                    map.insert(key.to_string(), Ok(part));
+                }
+                break;
+            }
+            if part == boundary {
+                if let Some(key) = &current_key {
+                    let mut part = current_part.join(&b'\n');
+                    if part.ends_with(&[b'\r']) {
+                        part.pop();
+                    }
+                    map.insert(key.to_string(), Ok(part));
+                }
+                current_part = vec![];
+                current_key = None;
+                ignore_line = 0;
+                continue;
+            }
+            if part.starts_with(b"Content-Disposition: form-data; name=") {
+                let headers = part
+                    .split(|byte| byte == &b';')
+                    .filter(|header| !header.is_empty())
+                    .collect::<Vec<_>>();
+                if headers.len() < 2 {
+                    continue;
+                }
+                let name = headers[1].split(|byte| byte == &b'=').collect::<Vec<_>>();
+                if name.len() != 2 {
+                    continue;
+                }
+                let mkey = String::from_utf8_lossy(name[1])
+                    .as_ref()
+                    .trim_end()
+                    .trim_matches('"')
+                    .to_owned();
+
+                if map.contains_key::<str>(&mkey) {
+                    current_key = Some(mkey.to_owned());
+                }
+                continue;
+            } else if let Some(_) = &current_key {
+                current_part.push(part);
+            }
+        }
+    }
+}
+#[cfg(test)]
+mod test {
+    use crate::{
+        handling::routes::Data,
+        utils::mime::mime_enum::Mime::{ApplicationXWwwFormUrlencoded, MultipartFormData},
+    };
+
+    use super::Request;
+
+    #[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,
+            cookies: None,
+            mime_type: Some(ApplicationXWwwFormUrlencoded),
+        };
+        let data = Data {
+            buffer: b"message=23&message1=24".to_vec(),
+            is_complete: true,
+        };
+        let map = req.get_post_data(&["message", "message1"], &data).unwrap();
+        assert_eq!(
+            &b"23".to_vec(),
+            map.get("message").unwrap().as_ref().unwrap()
+        );
+        assert_eq!(
+            &b"24".to_vec(),
+            map.get("message1").unwrap().as_ref().unwrap()
+        );
+        let req = Request {
+            uri: "",
+            headers: vec!["Content-Type: multipart/form-data; boundary=\"boundary\"".to_string()],
+            method: crate::handling::methods::Method::Post,
+            cookies: None,
+            mime_type: Some(MultipartFormData),
+        };
+        let data = Data {
+            buffer: b"--boundary\r
+Content-Disposition: form-data; name=\"field1\"\r
+\r
+value1\r
+--boundary\r
+Content-Disposition: form-data; name=\"field2\"; filename=\"example.txt\"\r
+\r
+va\nlue2\r
+--boundary--\r
+"
+            .to_vec(),
+            is_complete: true,
+        };
+        let map = req.get_post_data(&["field1", "field2"], &data).unwrap();
+
+        assert_eq!(
+            &b"value1".to_vec(),
+            map.get("field1").unwrap().as_ref().unwrap()
+        );
+        assert_eq!(
+            &b"va\nlue2".to_vec(),
+            map.get("field2").unwrap().as_ref().unwrap()
+        );
+    }
+}
diff --git a/core/http/src/handling/request/mod.rs b/core/http/src/handling/request/mod.rs
index 23c9f1a..54da4ad 100644
--- a/core/http/src/handling/request/mod.rs
+++ b/core/http/src/handling/request/mod.rs
@@ -1,5 +1,6 @@
 mod cookies;
 mod datatypes;
+mod form_utils;
 mod request_impl;
-pub use cookies::extract_cookies_from_vec;
+mod request_mime;
 pub use datatypes::{MediaType, ParseFormError, Request};
diff --git a/core/http/src/handling/request/request_impl.rs b/core/http/src/handling/request/request_impl.rs
index 2c582ea..747cd23 100644
--- a/core/http/src/handling/request/request_impl.rs
+++ b/core/http/src/handling/request/request_impl.rs
@@ -1,15 +1,6 @@
-// use std::net::SocketAddr;
+use crate::handling::methods::Method;
 
-use std::collections::HashMap;
-
-use crate::{
-    handling::{methods::Method, routes::Data},
-    utils::mime::mime_enum::Mime,
-};
-
-use super::datatypes::{ParseErrors, ParseFormError, Request};
-
-static TWO_NEWLINES: u8 = 3;
+use super::Request;
 
 impl Request<'_> {
     pub fn can_have_body(&self) -> bool {
@@ -24,273 +15,4 @@ impl Request<'_> {
             _ => false,
         }
     }
-    pub fn get_get_form_keys<'a>(
-        &'a self,
-        keys: &'a [&str],
-    ) -> Result<HashMap<&str, Result<&str, ParseFormError>>, ParseFormError> {
-        let data = if let Some(val) = self.uri.split_once('?') {
-            val
-        } else {
-            return Err(ParseFormError {
-                error: ParseErrors::NoData,
-            });
-        };
-        let data = data
-            .1
-            .split("&")
-            .map(|kvp| kvp.split_once("="))
-            .collect::<Vec<Option<(&str, &str)>>>();
-
-        let mut values: HashMap<&str, &str> = HashMap::new();
-        for kvp in data {
-            let kvp = if let Some(kvp) = kvp {
-                kvp
-            } else {
-                continue;
-            };
-            values.insert(kvp.0, kvp.1);
-        }
-        let mut response = HashMap::new();
-        for key in keys {
-            let entry = if let Some(val) = values.get(key) {
-                Ok(*val)
-            } else {
-                Err(ParseFormError {
-                    error: ParseErrors::NoData,
-                })
-            };
-            response.insert((*key).into(), entry);
-        }
-        Ok(response)
-    }
-
-    pub fn get_post_data<'a>(
-        &'a self,
-        keys: &[&'a str],
-        data: &Data,
-    ) -> Result<HashMap<String, Result<Vec<u8>, ParseFormError>>, ParseFormError> {
-        let boundary;
-        let post_type = if let Some(val) = self
-            .headers
-            .iter()
-            .find(|header| header.contains("Content-Type: "))
-        {
-            let content_type = val.trim().strip_prefix("Content-Type: ").unwrap();
-            let type_vec = content_type.split(';').collect::<Vec<&str>>();
-
-            boundary = if let Some(bound) = type_vec.iter().find(|part| part.contains(" boundary="))
-            {
-                bound
-                    .strip_prefix(" boundary=")
-                    .unwrap()
-                    .trim_end()
-                    .trim_matches('"')
-            } else {
-                ""
-            };
-            if let Ok(mime) = type_vec[0].trim().parse() {
-                mime
-            } else {
-                return Err(ParseFormError {
-                    error: ParseErrors::BadData,
-                });
-            }
-        } else {
-            return Err(ParseFormError {
-                error: ParseErrors::NoData,
-            });
-        };
-
-        let data = data.buffer.as_slice();
-        let mut keymap: HashMap<String, Result<Vec<u8>, ParseFormError>> =
-            HashMap::with_capacity(keys.len());
-
-        for key in keys {
-            keymap.entry(key.to_string()).or_insert(Err(ParseFormError {
-                error: ParseErrors::NoData,
-            }));
-        }
-
-        match post_type {
-            Mime::ApplicationXWwwFormUrlencoded => {
-                for kvp in data.split(|byte| *byte == b'&') {
-                    let kvp = kvp
-                        .split(|byte| *byte == b'=')
-                        .map(|list| list.to_vec())
-                        .collect::<Vec<Vec<u8>>>();
-                    let key = if let Some(kv) = kvp.get(0) {
-                        kv
-                    } else {
-                        return Err(ParseFormError {
-                            error: ParseErrors::BadData,
-                        });
-                    };
-                    let key = if let Ok(kv) = String::from_utf8(key.to_vec()) {
-                        kv
-                    } else {
-                        return Err(ParseFormError {
-                            error: ParseErrors::BadData,
-                        });
-                    };
-                    let value = kvp.get(1).ok_or(ParseFormError {
-                        error: ParseErrors::NoData,
-                    });
-                    let thing = if let Some(val) = keymap.get_mut(key.as_str()) {
-                        val
-                    } else {
-                        continue;
-                    };
-                    *thing = match value {
-                        Ok(val) => Ok(val.to_vec()),
-                        Err(err) => Err(err),
-                    }
-                }
-            }
-            Mime::MultipartFormData => {
-                let mut temp_bound = "--".to_string();
-                temp_bound.push_str(&format!("{boundary}"));
-                let end_boundary = format!("{temp_bound}--\r").as_bytes().to_owned();
-                temp_bound.push('\r');
-                let boundary = temp_bound.as_bytes();
-                Self::get_multipart_data(data, boundary, &end_boundary, &mut keymap);
-            }
-            _ => {
-                return Err(ParseFormError {
-                    error: ParseErrors::BadData,
-                })
-            }
-        };
-        Ok(keymap)
-    }
-    fn get_multipart_data(
-        data: &[u8],
-        boundary: &[u8],
-        end_boundary: &[u8],
-        map: &mut HashMap<String, Result<Vec<u8>, ParseFormError>>,
-    ) {
-        let parts = data.split(|byte| byte == &b'\n').collect::<Vec<&[u8]>>();
-        let mut current_part: Vec<&[u8]> = vec![];
-        let mut current_key: Option<String> = None;
-        let mut ignore_line = 0;
-        for part in parts {
-            if part == &[b'\r'] {
-                if let Some(_) = current_key {
-                    if ignore_line >= TWO_NEWLINES {
-                        current_part.push(&[b'\n']);
-                        continue;
-                    }
-                    ignore_line += 1;
-                }
-                continue;
-            }
-            if part == end_boundary {
-                if let Some(key) = &current_key {
-                    let mut part = current_part.join(&b'\n');
-                    if part.ends_with(&[b'\r']) {
-                        part.pop();
-                    }
-                    map.insert(key.to_string(), Ok(part));
-                }
-                break;
-            }
-            if part == boundary {
-                if let Some(key) = &current_key {
-                    let mut part = current_part.join(&b'\n');
-                    if part.ends_with(&[b'\r']) {
-                        part.pop();
-                    }
-                    map.insert(key.to_string(), Ok(part));
-                }
-                current_part = vec![];
-                current_key = None;
-                ignore_line = 0;
-                continue;
-            }
-            if part.starts_with(b"Content-Disposition: form-data; name=") {
-                let headers = part
-                    .split(|byte| byte == &b';')
-                    .filter(|header| !header.is_empty())
-                    .collect::<Vec<_>>();
-                if headers.len() < 2 {
-                    continue;
-                }
-                let name = headers[1].split(|byte| byte == &b'=').collect::<Vec<_>>();
-                if name.len() != 2 {
-                    continue;
-                }
-                let mkey = String::from_utf8_lossy(name[1])
-                    .as_ref()
-                    .trim_end()
-                    .trim_matches('"')
-                    .to_owned();
-
-                if map.contains_key::<str>(&mkey) {
-                    current_key = Some(mkey.to_owned());
-                }
-                continue;
-            } else if let Some(_) = &current_key {
-                current_part.push(part);
-            }
-        }
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use crate::handling::routes::Data;
-
-    use super::Request;
-
-    #[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,
-            cookies: None,
-        };
-        let data = Data {
-            buffer: b"message=23&message1=24".to_vec(),
-            is_complete: true,
-        };
-        let map = req.get_post_data(&["message", "message1"], &data).unwrap();
-        assert_eq!(
-            &b"23".to_vec(),
-            map.get("message").unwrap().as_ref().unwrap()
-        );
-        assert_eq!(
-            &b"24".to_vec(),
-            map.get("message1").unwrap().as_ref().unwrap()
-        );
-        let req = Request {
-            uri: "",
-            headers: vec!["Content-Type: multipart/form-data; boundary=\"boundary\"".to_string()],
-            method: crate::handling::methods::Method::Post,
-            cookies: None,
-        };
-        let data = Data {
-            buffer: b"--boundary\r
-Content-Disposition: form-data; name=\"field1\"\r
-\r
-value1\r
---boundary\r
-Content-Disposition: form-data; name=\"field2\"; filename=\"example.txt\"\r
-\r
-va\nlue2\r
---boundary--\r
-"
-            .to_vec(),
-            is_complete: true,
-        };
-        let map = req.get_post_data(&["field1", "field2"], &data).unwrap();
-
-        assert_eq!(
-            &b"value1".to_vec(),
-            map.get("field1").unwrap().as_ref().unwrap()
-        );
-        assert_eq!(
-            &b"va\nlue2".to_vec(),
-            map.get("field2").unwrap().as_ref().unwrap()
-        );
-    }
 }
diff --git a/core/http/src/handling/request/request_mime.rs b/core/http/src/handling/request/request_mime.rs
new file mode 100644
index 0000000..4fb9f3f
--- /dev/null
+++ b/core/http/src/handling/request/request_mime.rs
@@ -0,0 +1,59 @@
+use crate::utils::mime::mime_enum::Mime;
+
+use super::datatypes::Request;
+
+impl Request<'_> {
+    pub fn extract_mime_from_vec(headers: &Vec<String>) -> Option<Mime> {
+        let Some(content_type_header) = headers
+            .iter()
+            .find(|header| header.starts_with("Content-Type: ")) else {
+            return None;
+        };
+        let content_type_string = content_type_header
+            .strip_prefix("Content-Type: ")
+            .unwrap()
+            .to_string();
+
+        let mime;
+        match content_type_string.split_once(';') {
+            Some(sub) => {
+                mime = if let Ok(a) = sub.0.trim().parse() {
+                    a
+                } else {
+                    return None;
+                };
+            }
+            None => {
+                mime = if let Ok(a) = content_type_string.trim().parse() {
+                    a
+                } else {
+                    return None;
+                };
+            }
+        }
+        Some(mime)
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use crate::{handling::request::Request, utils::mime::mime_enum::Mime};
+
+    #[test]
+    pub fn test_mime_parse_from_header_vec() {
+        let mut right = vec![
+            "GET / 23".to_string(),
+            "SDF:LKJSD:F".to_string(),
+            "Content-Type: text/plain".to_string(),
+            "SDF".to_string(),
+        ];
+        let mut wrong = vec!["SDF:LKJSD:F".to_string(), "SDF".to_string()];
+
+        assert_eq!(None, Request::extract_mime_from_vec(&mut wrong));
+        assert_eq!(
+            Mime::TextPlain,
+            Request::extract_mime_from_vec(&mut right).unwrap()
+        );
+        assert_eq!(None, Request::extract_mime_from_vec(&mut right));
+    }
+}
diff --git a/core/http/src/setup.rs b/core/http/src/setup.rs
old mode 100755
new mode 100644
index c7f4522..30e2bf7
--- a/core/http/src/setup.rs
+++ b/core/http/src/setup.rs
@@ -3,7 +3,7 @@ use std::thread::available_parallelism;
 use tokio::{net::TcpListener, signal::unix::{SignalKind, signal}, select};
 
 use crate::{
-    handlers::handlers::handle_connection,
+    handlers::handler::handle_connection,
     handling::routes::{Route, Uri},
 };
 
@@ -75,8 +75,6 @@ impl<'a> Config {
     /// # Panics
     /// Panics if there are no Mountpoints in the Confiuration to lauch, as well as when the there
     /// is no interrupt signal
-    ///
-    /// Panics if .
     pub async fn launch(self) {
         println!("Server launched from http://{}", self.address.local_addr().unwrap());
         let mut sigint = signal(SignalKind::interrupt()).unwrap();
diff --git a/site/src/main.rs b/site/src/main.rs
index af47897..f1fda07 100644
--- a/site/src/main.rs
+++ b/site/src/main.rs
@@ -62,6 +62,7 @@ fn post_hi_handler(request: Request, data: Data) -> Outcome<Response, Status, Da
     if data.is_empty() {
         return Outcome::Forward(data);
     }
+    println!("{:?}", request.get_post_data(&["message"], &data));
     let dat = if let Ok(val) = request.get_post_data(&["message"], &data) {
         post_hi(String::from_utf8_lossy(val.get("message").unwrap().as_ref().unwrap()).to_string())
     } else {
-- 
GitLab