server_lib/server/
api_server.rs

1use crate::multithreading::thread_pool::ThreadPool;
2use crate::server::api_settings::ApiSettings;
3use crate::server::controller::ControllerBase;
4use crate::server::response_wrapper::response_wrapper::bad_request;
5use crate::server::response_wrapper::response_wrapper::method_not_allowed;
6use crate::server::request_parser::RequestParser;
7use std::io::prelude::*;
8use std::net::TcpListener;
9use std::net::TcpStream;
10
11pub struct ApiServer {
12    listener: TcpListener,
13    thread_pool: ThreadPool,
14    settings: ApiSettings,
15
16    controllers: Vec<Box<dyn ControllerBase>>,
17}
18
19unsafe impl Sync for ApiServer {}
20
21impl ApiServer {
22    pub fn new(settings: ApiSettings, controllers: Vec<Box<dyn ControllerBase>>) -> ApiServer {
23        let url = settings.create_url();
24
25        let listener = match TcpListener::bind(&url) {
26            Ok(val) => {
27                println!("Successfully binded to url {}", &url);
28                val
29            }
30            Err(e) => {
31                panic!("Cannot bind tcp listenter to url {} with error {}", &url, e)
32            }
33        };
34
35        let thread_pool = ThreadPool::new(4);
36        ApiServer {
37            listener,
38            settings,
39            thread_pool,
40            controllers,
41        }
42    }
43
44    pub fn start(&'static self) {
45        for stream in self.listener.incoming() {
46            let stream = match stream {
47                Ok(val) => val,
48                _ => {
49                    println!("Erorr while creating stream!");
50                    continue;
51                }
52            };
53            self.thread_pool.execute(move || {
54                self.handle_connection(stream);
55            });
56        }
57    }
58
59    fn handle_connection(&self, mut stream: TcpStream) {
60        let mut buffer = vec![0; self.settings.buffer_size];
61        stream.read(&mut buffer).unwrap();
62        if ApiServer::is_fave_icon(&buffer) {
63            // or add some processing here
64            return;
65        }
66        // self.process_middleware();
67        self.process_contorollers(&buffer, &stream);
68    }
69
70    fn process_contorollers(&self, buffer: &Vec<u8>, mut stream: &TcpStream) {
71        let parsed_uri = &RequestParser::parse(buffer);
72
73        let controller = self.controllers.iter().find(move |el| {
74            let uri_route = &parsed_uri.route();
75            let route = el.route();
76            let slice: &str = route.as_ref();
77            uri_route.starts_with(slice)
78        });
79        let response = match controller {
80            Some(val) => {
81                let parsed_uri_option = Option::from(parsed_uri.clone());
82                let response = match parsed_uri.rest_method().as_ref() {
83                    "GET" => val.get(&parsed_uri_option),
84                    "POST" => val.post(&parsed_uri_option),
85                    "PUT" => val.put(&parsed_uri_option),
86                    "UPDATE" => val.update(&parsed_uri_option),
87                    "DELETE" => val.delete(&parsed_uri_option),
88                    _ => method_not_allowed(None),
89                };
90                response
91            }
92            _ => bad_request(None),
93        };
94
95        stream.write(response.as_bytes()).unwrap();
96        stream.flush().unwrap();
97    }
98
99    fn is_fave_icon(buffer: &Vec<u8>) -> bool {
100        buffer.starts_with(b"GET /favicon.ico HTTP/1.1\r\n")
101    }
102}