http_server_rs/
httpserver.rs

1use std::{collections::BTreeMap, io::Error, net::{TcpListener, TcpStream, ToSocketAddrs}, sync::{Arc, Mutex}};
2
3use crate::{executor::Executor, httpreader::HttpReader};
4
5
6pub struct HttpServer<T : Executor>
7{
8    listener : Option<TcpListener>,
9    handler : BTreeMap<String, HttpHandlerWrap>,
10    started : bool,
11    executor : T,
12    max_client_timeout_ms : u64,
13}
14
15impl<T : Executor> HttpServer<T>
16
17{
18    
19    pub fn new(max_client_timeout_ms : u64, executor : T) -> Self {
20        let server : HttpServer<T> = HttpServer {
21            listener : Option::None,
22            handler : BTreeMap::new(),
23            started : false,
24            executor,
25            max_client_timeout_ms,
26        };
27        return server;
28    }
29    
30    pub fn add_endpoint<F>(&mut self, path : &str, handler : F) 
31    where F : Sized + FnMut(HttpReader) + Send + Sync + 'static {
32        let value = Arc::new(Mutex::new(handler));
33        self.handler.insert(String::from(path), value);
34    }
35    
36    pub fn init_listener<SA : ToSocketAddrs>(&mut self, socket_address : SA) -> Result<TcpListener, Error> {
37        let listener = TcpListener::bind(socket_address);
38        if listener.is_err() {
39            return Result::Err(listener.unwrap_err());
40        } else {
41            let l = listener.unwrap();
42            let result : Result<TcpListener, Error> = Result::Ok(l.try_clone().unwrap());
43            self.listener = Option::Some(l);
44            return result;
45        }
46    }
47    
48    pub fn start<SA : ToSocketAddrs>(&mut self, socket_address : SA) -> Result<bool, Error> {
49        if self.listener.is_none() {
50            let init = self.init_listener(socket_address);
51            if init.is_err() {
52                return Result::Err(init.unwrap_err());
53            }
54        }
55        
56        if !self.started {        
57            self.started = true;
58            let listener_copy : &TcpListener = self.listener.as_ref().unwrap();
59            let max_client_timeout_ms = self.max_client_timeout_ms;
60            let map_copy = self.handler.clone();
61            for tcpstream in listener_copy.incoming() {
62                let map_copy_copy = map_copy.clone();
63                self.executor.execute_mut(move || {
64                    if tcpstream.is_ok() {
65                        HttpServer::<T>::handle_connection(tcpstream.unwrap(), map_copy_copy, max_client_timeout_ms);
66                    }
67                });
68            }
69        }
70        
71        return Result::Ok(true);
72    }
73    
74    fn handle_connection(tcpstream : TcpStream, mut handler_map : BTreeMap<String, HttpHandlerWrap>, max_client_timeout_ms : u64) {
75        let pre_check_http_reader = HttpReader::new(tcpstream, max_client_timeout_ms);
76        if pre_check_http_reader.is_ok() {
77            let http_reader = pre_check_http_reader.unwrap();
78            let handler = handler_map.get_mut(&http_reader.get_request_path());
79            if handler.is_none() {
80                let fallback_key = &String::from("*");
81                let fallback = handler_map.get_mut(fallback_key);
82                if fallback.is_some() {
83                    let mut unwrapped = fallback.unwrap().lock().unwrap();
84                    (unwrapped)(http_reader);
85                } else {
86                    http_reader.respond_404();
87                }
88            } else {
89                let mut unwrapped = handler.unwrap().lock().unwrap();
90                (unwrapped)(http_reader);
91            }
92        }
93    }
94    
95}
96
97type HttpHandler = dyn FnMut(HttpReader) + Send + Sync;
98type HttpHandlerWrap = Arc<Mutex<HttpHandler>>;