From 377b68cfcdd67762f17809a1408ef8b9bc71287f Mon Sep 17 00:00:00 2001
From: Darius Auding <Darius.auding@gmx.de>
Date: Sun, 23 Jul 2023 18:42:13 +0200
Subject: [PATCH] FIX: Uri Pretty print

---
 core/http/src/handlers/handler.rs            |  6 +-
 core/http/src/handling/request/form_utils.rs |  7 +-
 core/http/src/setup.rs                       | 25 +-----
 core/http/src/utils/url_utils/datatypes.rs   |  1 +
 core/http/src/utils/url_utils/uri.rs         | 80 +++++++++++++++-----
 site/src/main.rs                             |  5 +-
 site/templates/index.html                    |  2 +-
 7 files changed, 70 insertions(+), 56 deletions(-)

diff --git a/core/http/src/handlers/handler.rs b/core/http/src/handlers/handler.rs
index 258e2b7..93a556a 100644
--- a/core/http/src/handlers/handler.rs
+++ b/core/http/src/handlers/handler.rs
@@ -143,11 +143,7 @@ pub async fn handle_connection<T: AsyncRead + AsyncWrite + std::marker::Unpin>(m
             if !route.uri.compare_uri(&request.uri) {
                 continue;
             }
-            handled_response = Some((route.handler)(
-                request.clone()
-                ,
-                data.clone(),
-            ));
+            handled_response = Some((route.handler)(request.clone(), data.clone()));
 
             if let Some(Outcome::Forward(_)) = handled_response {
                 continue;
diff --git a/core/http/src/handling/request/form_utils.rs b/core/http/src/handling/request/form_utils.rs
index 5f2b81b..865da7b 100644
--- a/core/http/src/handling/request/form_utils.rs
+++ b/core/http/src/handling/request/form_utils.rs
@@ -248,18 +248,13 @@ impl Request {
 }
 #[cfg(test)]
 mod test {
-    use std::str::FromStr;
-
     use crate::{
         handling::{
             methods::Method,
             request::{datatypes::ParseErrors, ParseFormError},
             routes::Data,
         },
-        utils::{
-            mime::Mime::{ApplicationXWwwFormUrlencoded, MultipartFormData},
-            url_utils::Uri,
-        },
+        utils::mime::Mime::{ApplicationXWwwFormUrlencoded, MultipartFormData},
     };
 
     use super::Request;
diff --git a/core/http/src/setup.rs b/core/http/src/setup.rs
index 6b6e85b..4c5b0dd 100644
--- a/core/http/src/setup.rs
+++ b/core/http/src/setup.rs
@@ -11,7 +11,7 @@ use tokio_native_tls::{native_tls::{Identity, self}, TlsAcceptor};
 
 use crate::{
     handlers::handler::handle_connection,
-    handling::routes::Route, utils::{url_utils::Uri, vec_utils::remove_n},
+    handling::routes::Route, utils::url_utils::Uri,
 };
 #[cfg(feature = "secure")]
 use crate::handling::response::{Response, Status};
@@ -40,22 +40,6 @@ pub struct Config {
     tls_acceptor: TlsAcceptor,
 }
 
-impl MountPoint {
-    pub fn compare_with_uri(&self, uri: &mut Uri) -> bool {
-        let mut uri_iter = uri.parts().iter();
-        let to_remove_after_finish = self.mountpoint.parts().len();
-        for part in self.mountpoint.parts().iter() {
-            let Some(part_uri) = uri_iter.next() else {
-                return false;
-            };
-            if part != part_uri {
-                return false;
-            }
-        }
-        remove_n(uri.mut_parts(), to_remove_after_finish);
-        true
-    }
-}
 
 impl<'a> Config {
     /// Utility that checks if the given mointpoint is already taken. takes in the uri of the to be
@@ -78,7 +62,7 @@ impl<'a> Config {
             return self;
         }
         routes.sort_by(|a, b| a.rank.cmp(&b.rank));
-        let mut mount_message = format!("  >> \x1b[35m{}\x1b[0m\n", mountpoint);
+        let mut mount_message = format!("  >> \x1b[35m{}\x1b[0m\n", mountpoint.to_pretty_print_string());
         for (index, route) in routes.iter().enumerate() {
             let indent_sign = match index {
                 i if i == routes.len() - 1 => "└─",
@@ -86,11 +70,10 @@ impl<'a> Config {
             };
 
             mount_message += &format!(
-            "     \x1b[35m{indent_sign}\x1b[0m \x1b[36m(\x1b[0m{}\x1b[36m)\x1b[0m \x1b[32m{}\x1b[0m \x1b[34;4m{}\x1b[24m{}\x1b[0m\n",
+            "     \x1b[35m{indent_sign}\x1b[0m \x1b[36m(\x1b[0m{}\x1b[36m)\x1b[0m \x1b[32m{}\x1b[0m {}\n",
                 route.name.unwrap_or(""),
                 route.method,
-                mountpoint,
-                route.uri
+                route.uri.to_pretty_print_string(&mountpoint)
             )
         }
 
diff --git a/core/http/src/utils/url_utils/datatypes.rs b/core/http/src/utils/url_utils/datatypes.rs
index 8c94a3e..a5f89db 100644
--- a/core/http/src/utils/url_utils/datatypes.rs
+++ b/core/http/src/utils/url_utils/datatypes.rs
@@ -5,6 +5,7 @@ use crate::utils::urlencoded::UrlEncodeData;
 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
 pub struct Uri {
     pub(super) parts: Vec<UrlEncodeData>,
+    pub raw: String,
 }
 
 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
diff --git a/core/http/src/utils/url_utils/uri.rs b/core/http/src/utils/url_utils/uri.rs
index a8a72bf..3a726a3 100644
--- a/core/http/src/utils/url_utils/uri.rs
+++ b/core/http/src/utils/url_utils/uri.rs
@@ -1,12 +1,27 @@
 use std::str::FromStr;
 
-use crate::utils::{url_utils::datatypes::RawUriElement, urlencoded::UrlEncodeData};
+use crate::{
+    setup::MountPoint,
+    utils::{url_utils::datatypes::RawUriElement, urlencoded::UrlEncodeData, vec_utils::remove_n},
+};
 
 use super::datatypes::{ParseUriError, RawUri, Uri};
 
+impl MountPoint {
+    pub fn compare_with_uri(&self, uri: &mut Uri) -> bool {
+        if !uri.raw.starts_with(&self.mountpoint.raw) {
+            return false;
+        }
+        let to_remove_after_finish = self.mountpoint.parts.len();
+        remove_n(uri.mut_parts(), to_remove_after_finish);
+        true
+    }
+}
+
 impl Uri {
     pub fn new(parts: Vec<&str>) -> Self {
         Self {
+            raw: "/".to_owned() + &parts.join("/"),
             parts: parts.into_iter().map(UrlEncodeData::from_raw).collect(),
         }
     }
@@ -28,6 +43,18 @@ impl Uri {
         }
         true
     }
+    pub(crate) fn to_pretty_print_string(&self) -> String {
+        if self.parts.is_empty() {
+            "/".to_string()
+        } else {
+            let url = self
+                .parts
+                .iter()
+                .map(|part| part.encoded())
+                .collect::<Vec<_>>();
+            "/".to_string() + &url.join("/")
+        }
+    }
 }
 
 impl RawUri {
@@ -35,7 +62,7 @@ impl RawUri {
         let mut result = Self {
             infinte_end: false,
             parts: Vec::with_capacity(parts.len()),
-            raw_string: "/".to_owned() + &parts.join("/"),
+            raw_string: parts.join("/"),
         };
         for part in parts {
             if part.starts_with('<') && part.ends_with("..>") {
@@ -52,15 +79,15 @@ impl RawUri {
         }
         result
     }
-    pub fn compare_uri(self, uri: &Uri) -> bool {
+    pub fn compare_uri(&self, uri: &Uri) -> bool {
         let mut iter_comp = uri.parts.iter();
-        let mut counter = 0;
+        if uri.parts().len() != self.parts.len() && !self.infinte_end {
+            return false;
+        }
         for element in self.parts.iter() {
-            counter += 1;
             let Some(compare_element) = iter_comp.next() else {
                 return false;
             };
-
             if *element == RawUriElement::Variable {
                 continue;
             }
@@ -72,11 +99,19 @@ impl RawUri {
                 return false;
             }
         }
-        if counter > self.parts.len() && !self.infinte_end {
-            return false;
+        if uri.parts.len() > self.parts.len() && self.infinte_end {
+            return true;
         }
         true
     }
+    pub(crate) fn to_pretty_print_string(&self, is_after: &Uri) -> String {
+        let is_after = is_after.to_pretty_print_string();
+        if is_after == "/" {
+            format!("\x1b[34;4m/\x1b[24m{}\x1b[0m", self)
+        } else {
+            format!("\x1b[34;4m{is_after}/\x1b[24m{self}\x1b[0m")
+        }
+    }
 }
 
 impl std::fmt::Display for RawUri {
@@ -87,23 +122,22 @@ impl std::fmt::Display for RawUri {
 
 impl std::fmt::Display for Uri {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        let url = self
-            .parts
-            .iter()
-            .map(|part| part.encoded())
-            .collect::<Vec<_>>();
-        write!(f, "/{}", url.join("/"))
+        if self.parts.is_empty() {
+            write!(f, "/")
+        } else {
+            let url = self
+                .parts
+                .iter()
+                .map(|part| part.encoded())
+                .collect::<Vec<_>>();
+            write!(f, "{}", url.join("/"))
+        }
     }
 }
 
 impl FromStr for Uri {
     type Err = ParseUriError;
     fn from_str(s: &str) -> Result<Self, Self::Err> {
-        if s == "/" {
-            return Ok(Self {
-                parts: vec![UrlEncodeData::from_encoded("").unwrap()],
-            });
-        }
         let split = s.split('/');
         let mut result = Vec::new();
         for sub in split {
@@ -116,7 +150,10 @@ impl FromStr for Uri {
                 UrlEncodeData::from_raw(sub)
             });
         }
-        Ok(Self { parts: result })
+        Ok(Self {
+            parts: result,
+            raw: s.to_string(),
+        })
     }
 }
 
@@ -127,7 +164,7 @@ impl FromStr for RawUri {
         let mut result = Self {
             infinte_end: false,
             parts: Vec::new(),
-            raw_string: parts.join("/"),
+            raw_string: s.to_string(),
         };
         for part in parts {
             if part.is_empty() {
@@ -145,6 +182,7 @@ impl FromStr for RawUri {
                 .parts
                 .push(RawUriElement::Name(UrlEncodeData::from_raw(part)))
         }
+        println!("{:?}", result);
         Ok(result)
     }
 }
diff --git a/site/src/main.rs b/site/src/main.rs
index c98c439..2437a50 100644
--- a/site/src/main.rs
+++ b/site/src/main.rs
@@ -5,7 +5,8 @@ use http::handling::{
     response::{Response, Outcome, Status}, 
     file_handlers::NamedFile};
 
-fn static_files_handler(request: Request<>, _data: Data) -> Outcome<Response, Status, Data> {
+fn static_files_handler(request: Request, _data: Data) -> Outcome<Response, Status, Data> {
+    println!("{:?} {}", request.uri, request.uri);
     let response = static_files(&request.uri.to_string());
     let response = match response {
         Ok(dat) => Response {
@@ -56,7 +57,7 @@ async fn main() {
         format: None,
         handler: static_files_handler,
         name: Some("static files"),
-        uri: "".try_into().unwrap(),
+        uri: "<file..>".try_into().unwrap(),
         method: Method::Get,
         rank: 0
     };
diff --git a/site/templates/index.html b/site/templates/index.html
index 7dc2842..a14d4de 100644
--- a/site/templates/index.html
+++ b/site/templates/index.html
@@ -8,7 +8,7 @@
   <body>
     <header>
       <nav>
-        <div>LOGO</div>
+        <div><img src="/favicon.ico" alt="ICON" width="32" height="32" /></div>
         <div>
           <div>Dashboard</div>
           <div>Books</div>
-- 
GitLab