From d214b0bf8646ee7f2f0792bbf3b96db8dacc2468 Mon Sep 17 00:00:00 2001 From: mtgmonkey Date: Thu, 19 Jun 2025 09:50:39 -0400 Subject: [PATCH] add some text/* types --- src/main.rs | 72 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 18 deletions(-) diff --git a/src/main.rs b/src/main.rs index a1cedd8..cfbced4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,17 +27,14 @@ fn main() { } fn handle_connection(stream: TcpStream) { - let contents = match parse_connection_to_header(&stream) { + let filepath = match parse_connection_to_header(&stream) { Ok(request) => { println!("Request: {request}"); - match parse_header_to_filepath(request) { - Ok(filepath) => read_file(filepath), - Err(err) => Err(err), - } + parse_header_to_filepath(request) } Err(err) => Err(err), }; - respond(&stream, contents); + respond(&stream, filepath); } fn parse_connection_to_header(stream: &TcpStream) -> Result { @@ -52,7 +49,7 @@ fn parse_connection_to_header(stream: &TcpStream) -> Result Result { - let regex = Regex::new(r"GET /(?[^/].*|) HTTP/(1\.1|2)").unwrap(); + let regex = Regex::new(r"^GET /(?[^/].*|) HTTP/(1\.1|2)").unwrap(); match regex.captures(&request) { Some(captures) => Ok(captures["path"].to_string()), None => Err(HTTP_400_BAD_REQUEST), @@ -70,21 +67,60 @@ fn read_file(filename: String) -> Result { } } -fn respond(mut stream: &TcpStream, contents: Result) { - let (status, length, contents) = match contents { - Ok(contents) => - ( format!("HTTP/1.1 {HTTP_200_OK}") - , contents.len() - , contents - ), +fn get_file_extension(filename: String) -> Option { + let regex = Regex::new(r"^.*\.(?[a-z]+)$").unwrap(); + match regex.captures(&filename) { + Some(captures) => Some(captures["extension"].to_string()), + None => None, + } +} + +fn get_content_type(filename: String) -> Option { + let header = "Content-Type:"; + match &get_file_extension(filename) { + Some(val) if val == "js" => Some(format!("{header} text/javascript")), + Some(val) if val == "html" => Some(format!("{header} text/html")), + Some(val) if val == "css" => Some(format!("{header} text/css")), + Some(val) if val == "png" => Some(format!("{header} image/png")), + Some(val) if val == "jpg" => Some(format!("{header} image/jpeg")), + Some(val) if val == "jpeg" => Some(format!("{header} image/jpeg")), + _ => None, + } +} + +fn respond(mut stream: &TcpStream, filename: Result) { + let (status, headers, contents) = match filename { + Ok(filename) => { + let filename = match filename { + val if val == "".to_string() => "index.html".to_string(), + filename => filename, + }; + let contents = read_file(filename.clone()); + let content_type = match get_content_type(filename) { + Some(header) => format!("{header}\r\n"), + None => "".to_string(), + }; + match contents { + Ok(contents) => + ( format!("HTTP/1.1 {HTTP_200_OK}") + , format!("Content-Length: {}\r\n{content_type}\r\n", contents.len()) + , contents + ), + Err(err) => + ( format!("HTTP/1.1 {err}") + , format!("Content-Length: {}\r\nContent-Type: text/html\r\n", "404 NOT FOUNDPage not found. Check that you typed the address correctly, or contact the site owner.".len()) + , "404 NOT FOUNDPage not found. Check that you typed the address correctly, or contact the site owner.".to_string() + ), + } + }, Err(err) => ( format!("HTTP/1.1 {err}") - , "404 NOT FOUNDPage not found. Check that you typed the address correctly, or contact the site owner.".len() + , format!("Content-Length: {}\r\nContent-Type: text/html\r\n", "404 NOT FOUNDPage not found. Check that you typed the address correctly, or contact the site owner.".len()) , "404 NOT FOUNDPage not found. Check that you typed the address correctly, or contact the site owner.".to_string() ), - }; - println!("Response: {status}\r\nContent-Length: {length}\r\n\r\n{contents}"); + }; + println!("Response: {status}\r\n{headers}\r\n{contents}"); stream - .write_all(format!("{status}\r\nContent-Length: {length}\r\n\r\n{contents}").as_bytes()) + .write_all(format!("{status}\r\n{headers}\r\n{contents}").as_bytes()) .expect("Error writing to stream"); }