From 39889425fb4f96aef011ec7b4cb7b7eb5085de76 Mon Sep 17 00:00:00 2001
From: Darius Auding <Darius.auding@gmx.de>
Date: Fri, 9 Jun 2023 21:17:37 +0200
Subject: [PATCH] Working on new get post data function

---
 core/http/src/handling/request.rs | 327 ++++++++++++++++++------------
 site/src/main.rs                  |  20 +-
 2 files changed, 202 insertions(+), 145 deletions(-)

diff --git a/core/http/src/handling/request.rs b/core/http/src/handling/request.rs
index 09f5db6..8605de4 100644
--- a/core/http/src/handling/request.rs
+++ b/core/http/src/handling/request.rs
@@ -110,119 +110,176 @@ impl Request<'_> {
         }
         Ok(response)
     }
-    pub fn get_post_text_form_key(
+
+    pub fn get_post_data(
         &self,
         keys: &[&str],
         data: &Data,
-    ) -> Result<HashMap<&str, Result<&str, ParseFormError>>, ParseFormError> {
-        let mut post_type = self
+    ) -> Result<HashMap<&str, Result<Vec<u8>, ParseFormError>>, ParseFormError> {
+        let mut post_type = if let Some(val) = self
             .headers
             .iter()
             .find(|header| header.contains("Content-Type: "))
-            .unwrap()
-            .to_string();
-
-        post_type = post_type
-            .strip_prefix("Content-Type: ")
-            .unwrap()
-            .to_string();
-
-        let post_type: Vec<&str> = post_type.trim().split(';').collect();
-        let mime_type = post_type[0].parse::<Mime>().unwrap();
-
-        let mut result = HashMap::new();
-        match mime_type {
-            Mime::ApplicationXWwwFormUrlencoded => {
-                let data = String::from_utf8(data.buffer.clone()).unwrap();
-                let kvps = data
-                    .split("&")
-                    .map(|kvp| kvp.split_once("=").unwrap())
-                    .collect::<HashMap<&str, &str>>();
-
-                for key in keys {
-                    let entry = if let Some(val) = kvps.get(key) {
-                        Ok(*val)
-                    } else {
-                        Err(ParseFormError {
-                            error: ParseErrors::NoData,
-                        })
-                    };
-                    result.insert(*key, entry);
-                }
-                Ok(result)
+        {
+            if let Ok(Type) = val.strip_prefix("Content-Type: ").unwrap().trim().parse() {
+                Type
+            } else {
+                return Err(ParseFormError {
+                    error: ParseErrors::NoData,
+                });
             }
-            Mime::MultipartFormData => {
-                let from_req = post_type[1..]
-                    .iter()
-                    .find(|val| val.contains("boundary="))
-                    .unwrap()
-                    .strip_prefix("boundary=")
-                    .unwrap();
-                let mut boundary = b"--".to_vec();
-                boundary.extend_from_slice(from_req.trim_matches('"').as_bytes());
-                let mut end_boundary = boundary.clone();
-                end_boundary.extend_from_slice(b"--");
-                boundary.extend_from_slice(&[b'\r']);
-                let parts = data
-                    .buffer
-                    .split(|byte| byte == &b'\n')
-                    .collect::<Vec<&[u8]>>();
+        } else {
+            return Err(ParseFormError {
+                error: ParseErrors::NoData,
+            });
+        };
 
-                let mut boundary_found = false;
-                let mut current_key: Option<usize> = None;
-                let mut result: Vec<Vec<u8>> = vec!["".into(); keys.len()];
-                for part in parts {
-                    if part == [] {
-                        continue;
-                    }
-                    if part == end_boundary {
-                        break;
-                    }
-                    if !boundary_found && part == boundary {
-                        current_key = None;
-                        boundary_found = true;
-                        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])
-                            .to_string()
-                            .trim_end()
-                            .trim_matches('"')
-                            .to_owned();
-                        let mut index = 0;
-                        for i in keys {
-                            if *i == mkey {
-                                current_key = Some(index);
-                            }
-                            index += 1;
-                        }
-                        boundary_found = false;
-                    } else if let Some(key) = current_key {
-                        result[key].extend_from_slice(part);
-                        result[key].extend_from_slice(&[b'\n']);
-                    }
-                }
-                Ok(result
-                    .iter()
-                    .map(|arr| String::from_utf8(arr.to_vec()).unwrap().trim().into())
-                    .collect())
-            }
+        let data = data.buffer.as_slice();
+        let mut keymap: HashMap<&str, Option<&[u8]>> = HashMap::with_capacity(keys.len());
+        for i in keys {
+            keymap.entry(i).or_default();
+        }
+        match post_type {
+            Mime::ApplicationXWwwFormUrlencoded => Ok(()),
             _ => Err(ParseFormError {
                 error: ParseErrors::BadData,
             }),
-        }
+        };
+        todo!()
     }
+
+    // pub fn get_post_text_form_key(
+    //     &self,
+    //     keys: &[&str],
+    //     data: &Data,
+    // ) -> Result<HashMap<&str, Result<&str, ParseFormError>>, ParseFormError> {
+    //     let mut post_type = self
+    //         .headers
+    //         .iter()
+    //         .find(|header| header.contains("Content-Type: "))
+    //         .unwrap()
+    //         .to_string();
+    //
+    //     post_type = post_type
+    //         .strip_prefix("Content-Type: ")
+    //         .unwrap()
+    //         .to_string();
+    //
+    //     let post_type: Vec<&str> = post_type.trim().split(';').collect();
+    //     let mime_type = post_type[0].parse().unwrap();
+    //
+    //     // let data = String::from_utf8(vec)
+    //
+    //     let mut result = HashMap::new();
+    //     match mime_type {
+    //         Mime::ApplicationXWwwFormUrlencoded => {
+    //             let data = String::from_utf8(data.buffer.clone()).unwrap();
+    //             let kvps = data
+    //                 .split("&")
+    //                 .map(|kvp| kvp.split_once("=").unwrap())
+    //                 .collect::<HashMap<&str, &str>>();
+    //
+    //             for key in keys {
+    //                 let entry = if let Some(val) = kvps.get(key) {
+    //                     Ok(*val)
+    //                 } else {
+    //                     Err(ParseFormError {
+    //                         error: ParseErrors::NoData,
+    //                     })
+    //                 };
+    //                 result.insert(*key, entry);
+    //             }
+    //             Ok(result)
+    //         }
+    //         Mime::MultipartFormData => {
+    //             let from_req = post_type[1..]
+    //                 .iter()
+    //                 .find(|val| val.contains("boundary="))
+    //                 .unwrap()
+    //                 .strip_prefix("boundary=")
+    //                 .unwrap();
+    //             let mut boundary = b"--".to_vec();
+    //             boundary.extend_from_slice(from_req.trim_matches('"').as_bytes());
+    //             let mut end_boundary = boundary.clone();
+    //             end_boundary.extend_from_slice(b"--");
+    //             boundary.extend_from_slice(&[b'\r']);
+    //             let parts = data
+    //                 .buffer
+    //                 .split(|byte| byte == &b'\n')
+    //                 .collect::<Vec<&[u8]>>();
+    //
+    //             let mut boundary_found = false;
+    //             let mut current_key: Option<&str> = None;
+    //             let mut result: HashMap<&str, Vec<u8>> = HashMap::new();
+    //             for part in parts {
+    //                 if part == [] {
+    //                     continue;
+    //                 }
+    //                 if part == end_boundary {
+    //                     break;
+    //                 }
+    //                 if !boundary_found && part == boundary {
+    //                     current_key = None;
+    //                     boundary_found = true;
+    //                     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();
+    //                     for i in keys {
+    //                         if *i == mkey {
+    //                             current_key = Some(&mkey);
+    //                         }
+    //                     }
+    //                     boundary_found = false;
+    //                 } else if let Some(key) = current_key {
+    //                     if None == result.get(key) {
+    //                         result.insert(key, part.to_vec());
+    //                         continue;
+    //                     }
+    //                     result.get_mut(key).unwrap().extend_from_slice(part);
+    //                 }
+    //             }
+    //             if result.len() == 0 {
+    //                 return Err(ParseFormError {
+    //                     error: ParseErrors::NoData,
+    //                 });
+    //             }
+    //             let return_result: HashMap<&str, Result<&str, ParseErrors>> =
+    //                 HashMap::with_capacity(keys.len());
+    //
+    //             for key in keys {
+    //                 let val = result.get(key).ok_or(ParseFormError {
+    //                     error: ParseErrors::NoData,
+    //                 }).map(|value| String::from_utf8(value))
+    //                 let val = if let Ok(str) = String::from_utf8(val) {
+    //                     Ok(str)
+    //                 } else {
+    //                     Err(ParseFormError {
+    //                         error: ParseErrors::BadData,
+    //                     })
+    //                 };
+    //             }
+    //         }
+    //         _ => Err(ParseFormError {
+    //             error: ParseErrors::BadData,
+    //         }),
+    //     }
+    // }
 }
 
 #[cfg(test)]
@@ -231,38 +288,38 @@ mod test {
 
     use super::Request;
 
-    #[test]
-    fn try_post_text() {
-        let req = Request {
-            uri: "",
-            headers: vec!["Content-Type: multipart/form-data;boundary=\"boundary\"".to_string()],
-            method: crate::handling::methods::Method::Post,
-        };
-        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\"\n\r
-\r
-value2\r
---boundary--"
-                .to_vec(),
-            is_complete: true,
-        };
-        assert_eq!(
-            "value1",
-            req.get_post_text_form_key(&["field1"], &data).unwrap()[0]
-        );
-        assert_eq!(
-            "value2",
-            req.get_post_text_form_key(&["field2"], &data).unwrap()[0]
-        );
-        assert_eq!(
-            vec!["value1", "value2"],
-            req.get_post_text_form_key(&["field1", "field2"], &data)
-                .unwrap()
-        )
-    }
+    //     #[test]
+    //     fn try_post_text() {
+    //         let req = Request {
+    //             uri: "",
+    //             headers: vec!["Content-Type: multipart/form-data;boundary=\"boundary\"".to_string()],
+    //             method: crate::handling::methods::Method::Post,
+    //         };
+    //         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\"\n\r
+    // \r
+    // value2\r
+    // --boundary--"
+    //                 .to_vec(),
+    //             is_complete: true,
+    //         };
+    //         assert_eq!(
+    //             "value1",
+    //             req.get_post_text_form_key(&["field1"], &data).unwrap()[0]
+    //         );
+    //         assert_eq!(
+    //             "value2",
+    //             req.get_post_text_form_key(&["field2"], &data).unwrap()[0]
+    //         );
+    //         assert_eq!(
+    //             vec!["value1", "value2"],
+    //             req.get_post_text_form_key(&["field1", "field2"], &data)
+    //                 .unwrap()
+    //         )
+    //     }
 }
diff --git a/site/src/main.rs b/site/src/main.rs
index 1005312..2a16f43 100644
--- a/site/src/main.rs
+++ b/site/src/main.rs
@@ -3,17 +3,17 @@ use std::{collections::HashMap, path::PathBuf};
 use http::handling::{
     file_handlers::NamedFile,
     methods::Method,
-    request::Request,
+    request::{Request, ParseFormError},
     response::{Outcome, Response, ResponseBody, Status},
     routes::{Data, Route},
 };
 
-fn hashmap_to_string(map: &HashMap<&str, &str>) -> String {
+fn hashmap_to_string(map: &HashMap<&str, Result<&str, ParseFormError>>) -> String {
     let mut result = String::new();
     for (key, value) in map {
         result.push_str(key);
         result.push('=');
-        result.push_str(value);
+        result.push_str(value.as_ref().unwrap());
         result.push(';');
     }
     result.pop(); // Remove the trailing semicolon if desired
@@ -21,7 +21,7 @@ fn hashmap_to_string(map: &HashMap<&str, &str>) -> String {
 }
 
 fn handle_static_hi(request: Request<'_>, data: Data) -> Outcome<Response, Status, Data> {
-    let keys = if let Ok(keys) = request.get_get_form_keys(vec!["asdf", "jkl"]) {
+    let keys = if let Ok(keys) = request.get_get_form_keys(&["asdf", "jkl"]) {
         keys
     } else {
         return Outcome::Forward(data);
@@ -62,12 +62,12 @@ fn post_hi_handler(request: Request, data: Data) -> Outcome<Response, Status, Da
     if data.is_empty() {
         return Outcome::Forward(data);
     }
-    let data = if let Ok(val) = request.get_post_text_form_key("message", &data) {
-        val
-    } else {
-        return Outcome::Failure(Status::BadRequest);
-    };
-    let dat = post_hi(data);
+    // let data = if let Ok(val) = request.get_post_text_form_key("message", &data) {
+    //     val
+    // } else {
+    //     return Outcome::Failure(Status::BadRequest);
+    // };
+    let dat = post_hi(String::from_utf8(data.buffer).unwrap());
     Outcome::Success(Response {
         headers: vec![
             format!("Content-Length: {}", dat.len()),
-- 
GitLab