From 676c4e7a181edd68e93b7a396b46722b77fc4073 Mon Sep 17 00:00:00 2001
From: Lorenz Stechauner <lorenz.stechauner@necronda.net>
Date: Sat, 15 May 2021 23:20:07 +0200
Subject: [PATCH] Add really basic request responses

---
 Cargo.toml          |  1 +
 src/http/handler.rs | 58 +++++++++++++++++++++++++++++++++++++++++----
 src/http/mod.rs     |  9 ++++---
 src/main.rs         |  1 +
 src/usimp/mod.rs    |  4 ++++
 5 files changed, 64 insertions(+), 9 deletions(-)
 create mode 100644 src/usimp/mod.rs

diff --git a/Cargo.toml b/Cargo.toml
index 4ecc087..9263978 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,3 +10,4 @@ edition = "2018"
 threadpool = "1.0"
 json = "0.12.4"
 openssl = {version = "0.10", features = ["vendored"]}
+chrono = "0.4"
diff --git a/src/http/handler.rs b/src/http/handler.rs
index c066182..5fb11ba 100644
--- a/src/http/handler.rs
+++ b/src/http/handler.rs
@@ -1,24 +1,74 @@
+use json;
+use chrono;
+use crate::usimp;
+use super::Method;
+
+pub struct HttpStream {
+    stream: super::Stream,
+    request_num: u32,
+    client_keep_alive: bool,
+    server_keep_alive: bool,
+}
 
 pub fn connection_handler(client: super::Stream) {
     let mut client = super::HttpStream {
         stream: client,
         request_num: 0,
+        client_keep_alive: true,
+        server_keep_alive: true,
     };
 
-    while client.request_num < super::REQUESTS_PER_CONNECTION {
+    while client.request_num < super::REQUESTS_PER_CONNECTION
+        && client.client_keep_alive
+        && client.server_keep_alive
+    {
         request_handler(&mut client);
         client.request_num += 1;
     }
 }
 
 fn request_handler(client: &mut super::HttpStream) {
+    let mut res = super::Response::new();
+    res.add_header("Server", "Locutus");
+    res.add_header("Date", chrono::Utc::now().format("%a, %d %b %Y %H:%M:%S GMT").to_string().as_str());
+
     let req = super::parser::parse_request(&mut client.stream).unwrap();
     println!("{} {}", req.method, req.uri);
 
-    let mut res = super::Response::new();
     let doc = "<!DOCTYPE html><html><head><title>Locutus Server</title></head><body><h1>Hello World! :D</h1></body></html>";
-    res.add_header("Content-Length", doc.len().to_string().as_str());
-    res.add_header("Content-Type", "text/html; charset=utf-8");
+
+    if !req.uri.starts_with("/")
+        || req.uri.contains("/./")
+        || req.uri.contains("/../")
+        || req.uri.ends_with("/..")
+    {
+        res.status(400);
+    } else if req.uri.contains("/.") {
+        res.status(404);
+    } else if req.uri.eq("/") {
+        res.status(200);
+        res.add_header("Content-Length", doc.len().to_string().as_str());
+        res.add_header("Content-Type", "text/html; charset=utf-8");
+    } else if req.uri.starts_with("/_usimp/") {
+        let parts: Vec<&str> = req.uri.split('/').collect();
+        match parts[2..] {
+            ["entity", entity] => res.status(501),
+            [func] => {
+                match usimp::is_valid(func) {
+                    true => match req.method {
+                        Method::POST => res.status(200),
+                        _ => res.status(405),
+                    },
+                    false => res.status(400),
+                }
+            },
+            _ => res.status(400),
+        }
+    } else {
+        res.status(404);
+    }
+
     res.send(&mut client.stream).unwrap();
     client.stream.write_all(doc.as_bytes()).unwrap();
+    client.server_keep_alive = false;
 }
diff --git a/src/http/mod.rs b/src/http/mod.rs
index 96f51d6..b582c79 100644
--- a/src/http/mod.rs
+++ b/src/http/mod.rs
@@ -16,11 +16,6 @@ pub enum Stream {
     Ssl(SslStream<TcpStream>),
 }
 
-pub struct HttpStream {
-    stream: Stream,
-    request_num: u32,
-}
-
 pub enum Method {
     GET,
     POST,
@@ -163,6 +158,10 @@ impl Response {
         }
     }
 
+    fn status(&mut self, status_code: u16) {
+        self.status = Status::from_code(status_code)
+    }
+
     fn add_header(&mut self, name: &str, value: &str) {
         self.header_fields.push(HeaderField {
             name: String::from(name),
diff --git a/src/main.rs b/src/main.rs
index 9a6e073..f1fac33 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,6 @@
 mod http;
 mod udp;
+mod usimp;
 
 use std::thread;
 use threadpool::ThreadPool;
diff --git a/src/usimp/mod.rs b/src/usimp/mod.rs
new file mode 100644
index 0000000..32fe35e
--- /dev/null
+++ b/src/usimp/mod.rs
@@ -0,0 +1,4 @@
+
+pub fn is_valid(evt: &str) -> bool {
+    false
+}