server_lib/server/
api_server.rs1use 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 return;
65 }
66 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}