102 lines
3.1 KiB
Rust
102 lines
3.1 KiB
Rust
use std::{
|
|
fs,
|
|
io::{prelude::*, BufReader},
|
|
net::TcpStream,
|
|
};
|
|
|
|
use crate::router;
|
|
|
|
#[allow(dead_code)]
|
|
struct IncomingRequest {
|
|
req_type: String,
|
|
path: String
|
|
// headers: Vec<String>
|
|
}
|
|
|
|
#[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<String>, 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()
|
|
}
|