http_server_rs/
httpserver.rs1use 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>>;