From 9b9f4971c4cb25eed58396835db5840f4e222a68 Mon Sep 17 00:00:00 2001
From: Darius Auding <Darius.auding@gmx.de>
Date: Tue, 9 May 2023 22:05:30 +0200
Subject: [PATCH] Add MIME support for the handler update routeing module

---
 core/http/Cargo.lock         |   7 +++++
 core/http/Cargo.toml         |   1 +
 core/http/src/handlers.rs    |  59 ++++++++++++++++++++++++++++-------
 core/http/src/routing.rs     |   5 ++-
 site/Cargo.lock              |   7 +++++
 site/{QLC-LS.jpg => img.jpg} | Bin
 6 files changed, 65 insertions(+), 14 deletions(-)
 rename site/{QLC-LS.jpg => img.jpg} (100%)

diff --git a/core/http/Cargo.lock b/core/http/Cargo.lock
index 755ed5e..6cd2bca 100644
--- a/core/http/Cargo.lock
+++ b/core/http/Cargo.lock
@@ -86,6 +86,7 @@ name = "http"
 version = "0.1.0"
 dependencies = [
  "ctrlc",
+ "mime",
  "quinn",
 ]
 
@@ -113,6 +114,12 @@ dependencies = [
  "cfg-if",
 ]
 
+[[package]]
+name = "mime"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
+
 [[package]]
 name = "mio"
 version = "0.8.6"
diff --git a/core/http/Cargo.toml b/core/http/Cargo.toml
index 34a4506..a5b887f 100644
--- a/core/http/Cargo.toml
+++ b/core/http/Cargo.toml
@@ -8,3 +8,4 @@ edition = "2021"
 [dependencies]
 quinn = "0.9.3"
 ctrlc = "3.2.5"
+mime = "0.3.17"
diff --git a/core/http/src/handlers.rs b/core/http/src/handlers.rs
index 944f60a..194eca3 100644
--- a/core/http/src/handlers.rs
+++ b/core/http/src/handlers.rs
@@ -2,8 +2,11 @@ use std::{
     fs,
     io::{BufRead, BufReader, Write},
     net::TcpStream,
+    path::PathBuf,
 };
 
+use mime::Mime;
+
 pub fn handle_connection(mut stream: TcpStream) {
     let buf_reader = BufReader::new(&mut stream);
     let http_request: Vec<_> = buf_reader
@@ -12,23 +15,57 @@ pub fn handle_connection(mut stream: TcpStream) {
         .take_while(|line| !line.is_empty())
         .collect();
 
-    let path_elements = http_request[0]
+    let path = parse_request(&http_request[0]);
+
+    let status_line;
+    let mime_type;
+    let contents = if let Ok(file) = fs::read(&path) {
+        status_line = "HTTP/1.1 200 OK";
+        mime_type = find_mimetype(&path.to_str().unwrap().to_string());
+        file
+    } else {
+        status_line = "HTTP/1.1 404 NOT FOUND";
+        mime_type = find_mimetype(&"html".to_string());
+        fs::read("404.html").unwrap()
+    };
+
+    println!("{mime_type}");
+
+    let response = format!(
+        "{}\r\nContent-Length: {}\r\nContent-Type: {}\r\n\r\n",
+        status_line,
+        contents.len(),
+        mime_type
+    );
+
+    stream.write_all(response.as_bytes()).unwrap();
+    stream.write(&contents).unwrap();
+}
+
+fn parse_request(request: &str) -> PathBuf {
+    let path_elements = request
         .split(" ")
         .nth(1)
         .unwrap()
         .split("/")
         .filter(|&val| val != ".." && val != "")
         .collect::<Vec<&str>>();
-    let mut path = String::from("./");
-    path.push_str(&path_elements.join("/"));
-    println!("{:?}", path_elements);
-    println!("{:?}", path);
-
-    let status_line = "HTTP/1.1 200 OK";
-    let contents = fs::read_to_string(path).unwrap_or(fs::read_to_string("404.html").unwrap());
-    let length = contents.len();
+    PathBuf::from(format!("./{}", path_elements.join("/")))
+}
 
-    let response = format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}");
+fn find_mimetype(filename: &String) -> Mime {
+    let parts: Vec<&str> = filename.split('.').collect();
 
-    stream.write_all(response.as_bytes()).unwrap();
+    let res = match parts.last() {
+        Some(v) => match *v {
+            "png" => mime::IMAGE_PNG,
+            "jpg" => mime::IMAGE_JPEG,
+            "json" => mime::APPLICATION_JSON,
+            "html" => mime::TEXT_HTML,
+            "css" => mime::TEXT_CSS,
+            &_ => mime::TEXT_PLAIN,
+        },
+        None => mime::TEXT_PLAIN,
+    };
+    return res;
 }
diff --git a/core/http/src/routing.rs b/core/http/src/routing.rs
index aee6f8a..2c5f74e 100644
--- a/core/http/src/routing.rs
+++ b/core/http/src/routing.rs
@@ -13,20 +13,19 @@ pub struct Route {
     // handler: fn(Request) -> Outcome,
     uri: &'static str,
     rank: isize,
-    format: Format,
+    format: Option<Format>,
 }
 
 impl Route {
     pub fn from(routeinfo: RoutInfo) -> Self {
         let rank = routeinfo.rank.unwrap_or(0);
-        let format = routeinfo.format.unwrap_or(Format::Plain);
         Route {
             name: routeinfo.name,
             method: routeinfo.method,
             // handler: routeinfo.handler,
             uri: routeinfo.path,
             rank,
-            format,
+            format: routeinfo.format,
         }
     }
 }
diff --git a/site/Cargo.lock b/site/Cargo.lock
index 498f9ed..7578765 100644
--- a/site/Cargo.lock
+++ b/site/Cargo.lock
@@ -86,6 +86,7 @@ name = "http"
 version = "0.1.0"
 dependencies = [
  "ctrlc",
+ "mime",
  "quinn",
 ]
 
@@ -113,6 +114,12 @@ dependencies = [
  "cfg-if",
 ]
 
+[[package]]
+name = "mime"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
+
 [[package]]
 name = "mio"
 version = "0.8.6"
diff --git a/site/QLC-LS.jpg b/site/img.jpg
similarity index 100%
rename from site/QLC-LS.jpg
rename to site/img.jpg
-- 
GitLab