diff --git a/index.html b/routes/index.html similarity index 100% rename from index.html rename to routes/index.html diff --git a/src/http/generators.rs b/src/http/generators.rs new file mode 100644 index 0000000..b562688 --- /dev/null +++ b/src/http/generators.rs @@ -0,0 +1,3 @@ +use super::*; + +pub fn generate_response(petition: HttpRequest) -> ProcessedResponse {} diff --git a/src/http/mod.rs b/src/http/mod.rs new file mode 100644 index 0000000..b466aac --- /dev/null +++ b/src/http/mod.rs @@ -0,0 +1,45 @@ +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; + +mod generators; +mod parsers; +mod types; + +use parsers::*; +use types::*; + +pub fn process_petition(stream: &mut TcpStream) -> ProcessedResponse { + let mut buffer = [0; 1024]; // TODO: manage this size + let _amount = stream.read(&mut buffer); + let petition = String::from_utf8_lossy(&buffer[..]); + let petition = parse_request(&petition); + + match petition { + Ok(petition_parsed) => { + let response_status = "200 OK"; + + let response_content = fs::read_to_string("./routes/index.html").unwrap(); + + let response: ProcessedResponse = ProcessedResponse { + data: format!( + "HTTP/1.1 {}\r\nContent-Length: {}\r\n\r\n{}", + response_status, + response_content.len(), + response_content + ), + status: 200, + }; + + response + } + Err(error) => { + let response: ProcessedResponse = ProcessedResponse { + data: format!("HTTP/1.1 {}\r\nContent-Length: 0\r\n\r\n", error), + status: error, + }; + + response + } + } +} diff --git a/src/http.rs b/src/http/parsers.rs similarity index 54% rename from src/http.rs rename to src/http/parsers.rs index 9678f90..e18f1a3 100644 --- a/src/http.rs +++ b/src/http/parsers.rs @@ -1,80 +1,8 @@ use std::collections::HashMap; -use std::fs; -use std::io::prelude::*; -use std::net::TcpStream; -// TODO: -// - we could complement status with a struct that stores the status and the error message. -// - an alternative is to have a status-error_mesage mapper in order to send an error explanation to the client -type Status = u16; -type Body<'a> = Option<&'a str>; +use super::*; -#[derive(Debug)] -pub struct ProcessedResponse { - pub data: String, - status: Status, -} - -type QueryParams<'a> = HashMap<&'a str, &'a str>; -type Headers<'a> = HashMap<&'a str, &'a str>; - -#[derive(Debug)] -struct HttpRequestQuery<'a> { - path: &'a str, - params: QueryParams<'a>, -} - -#[derive(Debug)] -struct HttpRequestLine<'a> { - method: &'a str, - version: &'a str, - query: HttpRequestQuery<'a>, -} - -#[derive(Debug)] -struct HttpRequest<'a> { - request: HttpRequestLine<'a>, - headers: Headers<'a>, - body: Body<'a>, -} - -pub fn process_petition(stream: &mut TcpStream) -> ProcessedResponse { - let mut buffer = [0; 1024]; // TODO: manage this size - let _amount = stream.read(&mut buffer); - let petition = String::from_utf8_lossy(&buffer[..]); - println!("Petition: {:?}", petition); - let petition = parse_request(&petition); - - match petition { - Ok(petition_parsed) => { - let response_status = "200 OK"; - - let response_content = fs::read_to_string("./index.html").unwrap(); - - let response: ProcessedResponse = ProcessedResponse { - data: format!( - "HTTP/1.1 {}\r\nContent-Length: {}\r\n\r\n{}", - response_status, - response_content.len(), - response_content - ), - status: 200, - }; - - response - } - Err(error) => { - let response: ProcessedResponse = ProcessedResponse { - data: format!("HTTP/1.1 {}\r\nContent-Length: 0\r\n\r\n", error), - status: error, - }; - - response - } - } -} - -fn parse_request(request_raw: &str) -> Result { +pub fn parse_request(request_raw: &str) -> Result { // TODO: study if better to use match if let Some((heading, rest)) = request_raw.split_once("\n") { if let Ok(request) = parse_request_block(heading) { diff --git a/src/http/types.rs b/src/http/types.rs new file mode 100644 index 0000000..8c18fbd --- /dev/null +++ b/src/http/types.rs @@ -0,0 +1,36 @@ +use std::collections::HashMap; + +// TODO: +// - we could complement status with a struct that stores the status and the error message. +// - an alternative is to have a status-error_mesage mapper in order to send an error explanation to the client +pub type Status = u16; +pub type Body<'a> = Option<&'a str>; + +#[derive(Debug)] +pub struct ProcessedResponse { + pub data: String, + pub status: Status, +} + +pub type QueryParams<'a> = HashMap<&'a str, &'a str>; +pub type Headers<'a> = HashMap<&'a str, &'a str>; + +#[derive(Debug)] +pub struct HttpRequestQuery<'a> { + pub path: &'a str, + pub params: QueryParams<'a>, +} + +#[derive(Debug)] +pub struct HttpRequestLine<'a> { + pub method: &'a str, + pub version: &'a str, + pub query: HttpRequestQuery<'a>, +} + +#[derive(Debug)] +pub struct HttpRequest<'a> { + pub request: HttpRequestLine<'a>, + pub headers: Headers<'a>, + pub body: Body<'a>, +} diff --git a/src/main.rs b/src/main.rs index 84a8ab7..7b7981a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,7 +16,6 @@ fn main() { let response = http::process_petition(&mut _stream); // TODO: manage error case - println!("About to responde: {:?}", response); let _amount = _stream.write(response.data.as_bytes()).unwrap(); _stream.flush().unwrap(); }