diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..683ae0d --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "miniweb" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..8bae0b3 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "miniweb" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/README.md b/README.md index acd7460..11b2864 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ # miniweb +A light weight rust web server I am working on for a bit of fun. +FOR EDUCATION PURPOSE ONLY, NOT RECCOMENDED FOR USE AT THIS TIME. \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..6e40cd2 --- /dev/null +++ b/index.html @@ -0,0 +1,3 @@ + +

Hello World

+ diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..1f4a337 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,59 @@ +use std::net::{TcpListener, TcpStream}; +use std::{println, io::{Read}}; +// use std::time::Duration; +mod methods; + +fn method_handler(mut stream: TcpStream) { + let mut packet = [0; 65535]; + let bytes_read = stream.read(&mut packet[..]); + match bytes_read { + Ok(n) if n >= 7 => { + if packet[0..3] == [0x47, 0x45, 0x54] { + println!("GET Method"); + + methods::get::handler(stream, &packet); + + } else if packet[0..4] == [0x48, 0x45, 0x41, 0x44] { + println!("HEAD Method"); + } else if packet[0..6] == [0x4F, 0x50, 0x49, 0x4F, 0x4E, 0x53] { + println!("OPTIONS Method"); + } else if packet[0..5] == [0x54, 0x52, 0x41, 0x43, 0x45] { + println!("TRACE Method"); + } else if packet[0..3] == [0x50, 0x55, 0x54] { + println!("PUT Method"); + } else if packet[0..6] == [0x44, 0x45, 0x4C, 0x45, 0x54, 0x45] { + println!("DELETE Method"); + } else if packet[0..4] == [0x50, 0x4F, 0x53, 0x54] { + println!("POST Method"); + } else if packet[0..5] == [0x50, 0x41, 0x54, 0x43, 0x48] { + println!("PATCH Method"); + } else if packet[0..7] == [0x43, 0x4F, 0x4E, 0x4E, 0x45, 0x43, 0x54] { + println!("CONNECT method"); + } else { + println!("Unknown Method"); + } + }, + Ok(_) => { + println!("Packet appears too small"); + }, + Err(_e) => { + println!("No data recieved"); + } + } + +} + +fn main() { + let listener = TcpListener::bind("0.0.0.0:80").unwrap(); + + for stream in listener.incoming() { + match stream { + Ok(stream) => { + method_handler(stream); + } + Err(_e) => { + println!("Couldn't conenct to client..."); + } + } + } +} diff --git a/src/methods.rs b/src/methods.rs new file mode 100644 index 0000000..40c83f3 --- /dev/null +++ b/src/methods.rs @@ -0,0 +1,13 @@ +enum Methods{ + GET, + // HEAD, + // OPTIONS, + // TRACE, + // PUT, + // DELETE, + // POST, + // PATCH, + // CONNECT, +} + +pub mod get; diff --git a/src/methods/get.rs b/src/methods/get.rs new file mode 100644 index 0000000..ec7c7e2 --- /dev/null +++ b/src/methods/get.rs @@ -0,0 +1,59 @@ +use std::net::TcpStream; +use std::io::{Write}; +use super::Methods; +use std::fs; + +struct Packet { + method: Methods, + path: String, + protocol_version: String, +} + +pub fn handler(stream: TcpStream, binary_packet: &[u8]) { + let string_packet = String::from_utf8_lossy(&binary_packet); + let packet_breakdown: Vec<&str> = string_packet.lines().collect(); + let mut header = packet_breakdown[0].split_whitespace(); + + let _ = header.next(); + + + let this_packet = Packet { + method: Methods::GET, + path: String::from(header.next().unwrap_or("/")), + protocol_version: String::from(header.next().unwrap_or("/")), + }; + + println!("{}",string_packet); + + response(stream, this_packet); +} + +fn response(mut stream: TcpStream, this_packet: Packet){ + let mut content = Vec::new(); + let code = get_content(this_packet.path, &mut content); + match code{ + 200 => { stream.write(&content); }, + 404 => { stream.write("404 Page not found".as_bytes()); }, + _ => println!("Unknown Error Code"), + }; + +} + +fn get_content(path: String, content: &mut Vec) -> i32 { + let mut this_path = ".".to_string() + &path; + if this_path == "./" { + this_path = "./index.html".to_string(); + } + + let data = match fs::read(this_path) { + Ok(vec) => vec, + Err(e) => return 404 + }; + + content.extend_from_slice(data.as_slice()); + return 200; +} + +// fn gen_header(){ +// +// } diff --git a/src/methods/test.html b/src/methods/test.html new file mode 100644 index 0000000..e69de29