ilmen_http/http/
server.rs1use 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
58fn 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}