use std::{ fs, io::{prelude::*, BufReader}, net::TcpStream, }; use crate::router; #[allow(dead_code)] struct IncomingRequest { req_type: String, path: String // headers: Vec } #[allow(unused_assignments)] pub fn handle_connection(mut stream: TcpStream) { // Create a new buffer reader with the stream data. let buf_reader = BufReader::new(&stream); // Store each line in a vector. let http_request: Vec<_> = buf_reader .lines() .map(|result| result.unwrap()) .take_while(|line| !line.is_empty()) .collect(); // Get the first line of the stream which contains request data. let request_line: String = http_request.first().expect("No request line found").to_string(); let mut response; // Split the request data on spaces into a vector. let req_vec: Vec<&str> = request_line.split(" ").collect(); let inc_request = IncomingRequest { req_type: req_vec[0].to_string(), path: req_vec[1].to_string(), }; // Handle 404. if inc_request.path.is_empty() { response = return_response("404"); } // Handle images. if inc_request.path.contains("images") { let mut public_route: String = "./public".to_string(); public_route.push_str(&inc_request.path); let image_data = fs::read(&public_route).unwrap(); let status_line = "HTTP/1.1 200 OK".to_string(); let response = format!( "{}\r\nContent-Length: {}\r\n\r\n", status_line, image_data.len() ); stream.write(response.as_bytes()).unwrap(); stream.write(&image_data).unwrap(); } else { response = return_response(&inc_request.path); stream.write(response.as_bytes()).unwrap(); } } #[allow(dead_code)] fn get_header(headers: Vec, needle: &str) -> String { let mut value = String::new(); for header in headers { let split_header: Vec<&str> = header.split(":").collect(); let header_key: String = split_header.first().expect("Nothing here").to_string(); if header_key == needle { value = split_header[1].to_string(); } } value } fn return_response(path_or_code: &str) -> String { let status_line: String; let contents: String; match path_or_code { "404" => { status_line = "HTTP/1.1 404 Not Found".to_string(); contents = fs::read_to_string("./public/404.html").unwrap(); }, "200" => { status_line = "HTTP/1.1 200 OK".to_string(); contents = fs::read_to_string("./public/index.html").unwrap(); }, &_ => { // Need to get the proper response based on the given path. status_line = "HTTP/1.1 200 OK".to_string(); contents = router::get_route_data(path_or_code); // status_line = "HTTP/1.1 404 Not Found".to_string(); } } let length = contents.len(); format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}") } pub fn path_exists(path: &str) -> bool { fs::metadata(path).is_ok() }