ssw/src/main.rs
2023-01-09 12:46:03 +01:00

140 lines
3.5 KiB
Rust

extern crate file_matcher;
use file_matcher::FileNamed;
use hello::{
ThreadPool,
};
use std::{
fs,
io::{prelude::*, BufReader},
net::{TcpListener, TcpStream},
collections::HashMap,
path::Path,
};
use config::Config;
fn main() {
//building config
let cfg = Config::builder()
.add_source(config::File::with_name("websrv_conf"))
.build()
.unwrap();
let cfg = cfg.try_deserialize::<HashMap<String, String>>().expect("Could not deserialize configuration");
println!("Starting with configuration: ");
for conf in &cfg {
println!("{:?}", conf);
}
let nbr_of_threads: usize = cfg
.get("threads")
.expect("Threads not found in config")
.parse()
.unwrap();
let default_bind_addr = String::from("0.0.0.0:7878");
let bind_addr = cfg
.get("bind_addr")
.unwrap_or(&default_bind_addr)
.to_string();
let default_webpage = String::from("index.html");
let webpage = cfg
.get("webpage")
.unwrap_or(&default_webpage)
.to_string();
let listener = TcpListener::bind(bind_addr).unwrap();
let pool = ThreadPool::new(nbr_of_threads);
for stream in listener.incoming() {
let stream = stream.unwrap();
let webp = webpage.clone();
pool.execute(move || {
handle_connection(stream, webp);
});
}
println!("Shutting down.");
}
fn search_page(page: &String) -> Option<String> {
if page == "/" {
match FileNamed::regex(r"index\.htm.*").within("./html").find() {
Ok(f) => {
return Some(fs::read_to_string(f).unwrap());
},
Err(_) => return None,
};
} else {
match FileNamed::regex(format!(r"{}\.htm.*", page)).within("./html").find() {
Ok(f) => {
let fpath = format!("./html/{:?}", f);
return Some(fs::read_to_string(f).unwrap());
},
Err(_) => return None,
};
}
}
///Analyze the request and answer it
///Returns the complete answer
fn analyze_request_line(line: Vec<&str>) -> String {
let req = String::from(line[0]);
let mut page = String::from(line[1]);
let proto = String::from(line[2]);
let mut ret_code = "404 NOT FOUND";
//Removing the leading / from the page if need be
if &page != "/" {
page.remove(0);
}
let content = match search_page(&page) {
Some(c) => {
*&mut ret_code = "200 OK";
c
},
None => {
fs::read_to_string("./html/err_pages/404.html").unwrap_or(String::from("404 not found"))
},
};
let length = content.len();
let returned_line = format!(
"{proto} {ret_code}\r\nContent-Length: {length}\r\n\r\n{content}"
);
return returned_line;
}
fn handle_connection(mut stream: TcpStream, webpage: String) {
let buf_reader = BufReader::new(&mut stream);
//for i in buf_reader.lines() {
// println!("{:?}", i);
//}
let mut req_lines = buf_reader.lines();
let mut request = match req_lines.next() {
Some(c) => c,
None => Ok(String::from("RIEN")),
};
let request = request.unwrap();
println!("!!{:?}", request);
//Some(Ok("GET /crabe HTTP/1.1"))
if &request != "RIEN" {
let request_analyze: Vec<&str> = request.split_whitespace().collect();
let ret_line = analyze_request_line(request_analyze);
stream.write_all(ret_line.as_bytes()).unwrap();
}
}