http_server_rs/
httpserver.rs

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