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 = "Locutus Server

Hello World! :D

"; - 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), } -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 +}