ilmen_http/http/
server.rs

1use std::io::prelude::*;
2use std::net::TcpListener;
3use std::net::TcpStream;
4use std::sync::atomic::AtomicBool;
5use std::sync::atomic::Ordering;
6use std::sync::Arc;
7use log::info;
8use log::trace;
9
10use crate::http::router::handle_request;
11use crate::http::requests::HTTPRequest;
12use crate::http::responses::HTTPResponse;
13use crate::http::configuration::ThreadPool;
14
15use super::router::Routes;
16use super::configuration::Config;
17
18
19#[derive(Default)]
20pub struct HttpServer {
21    configuration: Config, 
22    handler : Routes
23}
24
25impl HttpServer {
26
27    pub fn new(configuration: Config, handler : Routes) -> Self {
28        HttpServer {
29            configuration,
30            handler
31        }
32    } 
33
34   pub fn start(&self) {
35        info!("Opening connection and listening");
36        let config = self.configuration.clone();
37        info!("Start listening on {}", config.adresse());
38        let listener = TcpListener::bind(config.adresse()).unwrap();
39        info!("Initializing thread pool : {}", 5);
40        let pool = ThreadPool::new(5);
41        let term = Arc::new(AtomicBool::new(false));
42        signal_hook::flag::register(signal_hook::consts::SIGTERM, Arc::clone(&term)).unwrap();
43        while !term.load(Ordering::Relaxed) {
44            for stream in listener.incoming() {
45                let stream = stream.unwrap();
46                let routes = self.handler.clone();
47                let config = config.clone();
48    
49                pool.execute(move || {
50                    handle_connection(stream, routes, config);
51                });
52            }
53        }
54   } 
55}
56
57
58// PRIVATE
59fn handle_connection(mut stream: TcpStream, handler : Routes, config: Config) {
60    let mut buffer: Vec<u8> = vec![0; config.request_size()];
61    stream.read(&mut buffer).unwrap();
62
63    let response = 
64    HTTPRequest::try_from(buffer)
65        .map(|request |  handle_request(&request, handler, config))
66        .unwrap_or_else(HTTPResponse::from);
67        
68            
69    trace!("Response: {}", response.to_string());
70    write(stream, response.to_string());
71}
72
73fn write(mut stream : TcpStream, response: String) {
74    stream.write_all(response.as_bytes()).unwrap();
75    stream.flush().unwrap();
76}