diff options
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 187 |
1 files changed, 13 insertions, 174 deletions
diff --git a/src/main.rs b/src/main.rs index 2f61490..1ad6f26 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,171 +1,13 @@ +#![allow(unused)] +use itertools::Itertools; use std::collections::HashMap; -use std::fmt::format; -use std::io::{Read, Write}; +use std::io::{self, Read, Write}; use std::net::{TcpListener, TcpStream}; -use std::str; +use std::{str, thread}; -use itertools::{join, Itertools}; - -enum StatusCode { - // 2xx Success - Ok, - // Created = 201, - // Accepted = 202, - // NonAuthoritative = 203, - // NoContent = 204, - // ResetContent = 205, - // PartialContent = 206, - - // 4xx Client Error - BadRequest, - NotFound, -} - -type Endpoint = String; -type Target = String; - -#[derive(Debug)] -enum HTTPMethod { - Get((Endpoint, Target)), - Post((Endpoint, Target)), - Put((Endpoint, Target)), -} - -impl From<StatusCode> for String { - fn from(val: StatusCode) -> Self { - use StatusCode::*; - match val { - Ok => "200 OK".to_string(), - BadRequest => "400 Bad Request".to_string(), - NotFound => "404 Not Found".to_string(), - } - } -} - -impl From<HTTPMethod> for String { - fn from(val: HTTPMethod) -> Self { - use HTTPMethod::*; - match val { - Get((endpoint, target)) => "GET".to_string() + &endpoint + &target, - Post((endpoint, target)) => "POST".to_string() + &endpoint + &target, - Put((endpoint, target)) => "PUT".to_string() + &endpoint + &target, - } - } -} - -#[derive(Debug)] -struct Headers(HashMap<String, String>); - -impl From<&[&str]> for Headers { - fn from(value: &[&str]) -> Self { - let mut header_map = HashMap::new(); - for header in value.iter().filter(|val| !val.is_empty()) { - let (key, val) = header - .split_once(": ") - .expect("Should be splitable by :<space>"); - header_map.insert(key.to_string(), val.to_string()); - } - Headers(header_map) - } -} - -impl From<&str> for HTTPMethod { - fn from(val: &str) -> Self { - use HTTPMethod::*; - let request_line = val.split(' ').collect_vec(); - let (method, info) = (request_line[0], request_line[1]); - let info = info.chars().skip(1).collect::<String>() + &"/"; - let (endpoint, target) = info.split_once("/").expect("Should be splitable by /"); - match method { - "GET" => Get((endpoint.to_string(), target.to_string())), - "POST" => Post((endpoint.to_string(), target.to_string())), - _ => { - eprintln!("{method} Not Supported Yet"); - unreachable!() - } - } - } -} - -#[derive(Debug)] -struct Request { - method: HTTPMethod, - headers: Option<Headers>, - body: Option<String>, -} - -impl Request { - fn new(method: HTTPMethod, headers: Headers, body: String) -> Self { - let headers = if headers.0.len() == 0 { - None - } else { - Some(headers) - }; - let body = if body.is_empty() { None } else { Some(body) }; - Request { - method, - headers, - body, - } - } -} - -impl From<&str> for Request { - fn from(val: &str) -> Self { - let request: Vec<&str> = val.split("\r\n").collect(); - match &request[..] { - [request_line, headers @ .., body] => { - let (method, headers, body) = ( - HTTPMethod::from(*request_line), - Headers::from(headers), - body.to_string(), - ); - Request::new(method, headers, body) - } - _ => { - unreachable!(); - } - } - } -} - -struct Response { - version: String, - status: StatusCode, - headers: Option<Headers>, - body: Option<String>, -} - -impl Response { - fn new( - version: String, - status: StatusCode, - headers: Option<Headers>, - body: Option<String>, - ) -> Self { - Response { - version, - headers, - status, - body, - } - } -} - -impl Into<String> for Response { - fn into(self) -> String { - let status_line = format!("HTTP/{} {}", self.version, String::from(self.status)); - let headers = self - .headers - .unwrap_or(Headers(HashMap::new())) - .0 - .iter() - .map(|(key, value)| format!("{key}: {value}\r\n")) - .collect::<String>(); - let body = self.body.unwrap_or("".to_string()); - format!("{status_line}\r\n{headers}\r\n{body}") - } -} +use http_server_starter_rust::http_types::*; +use http_server_starter_rust::request::*; +use http_server_starter_rust::response::*; fn handle_client(mut stream: TcpStream) { // Buffer to store the data received from the client @@ -258,14 +100,10 @@ fn handle_client(mut stream: TcpStream) { }, } } - HTTPMethod::Post(target) => todo!(), - HTTPMethod::Put(target) => todo!(), + HTTPMethod::Post(_target) => todo!(), + HTTPMethod::Put(_target) => todo!(), } } - - // Prepare a response - // let response = b"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nHello, world!"; - // } Err(e) => { eprintln!("Failed to read from stream: {}", e); @@ -273,18 +111,19 @@ fn handle_client(mut stream: TcpStream) { } } -fn main() { +fn main() -> io::Result<()> { let listener = TcpListener::bind("127.0.0.1:4221").unwrap(); for stream in listener.incoming() { match stream { Ok(stream) => { - // println!("accepted new connection"); - handle_client(stream) + thread::spawn(move || handle_client(stream)); } Err(e) => { eprintln!("error: {}", e); } } } + + Ok(()) } |
