rust_web_server/server/
mod.rs

1#[cfg(test)]
2pub mod tests;
3pub mod example;
4
5use std::io::prelude::*;
6use std::borrow::Borrow;
7use std::net::{IpAddr, SocketAddr, TcpListener};
8use std::str::FromStr;
9
10use crate::request::{METHOD, Request};
11use crate::response::{Response, STATUS_CODE_REASON_PHRASE};
12use crate::app::App;
13use crate::application::Application;
14use crate::core::New;
15use crate::entry_point::{bootstrap, get_ip_port_thread_count, get_request_allocation_size, set_default_values};
16use crate::header::Header;
17use crate::log::Log;
18use crate::mime_type::MimeType;
19use crate::range::{ContentRange, Range};
20use crate::symbol::SYMBOL;
21use crate::thread_pool::ThreadPool;
22
23pub struct Server {}
24impl Server {
25    pub fn process_request(mut stream: impl Read + Write + Unpin, peer_addr: SocketAddr) -> Vec<u8> {
26        let request_allocation_size = get_request_allocation_size();
27        let mut buffer = vec![0; request_allocation_size as usize];
28        let boxed_read = stream.read(&mut buffer);
29        if boxed_read.is_err() {
30            let message = boxed_read.err().unwrap().to_string();
31            eprintln!("unable to read TCP stream {}", &message);
32
33            let raw_response = Server::bad_request_response(message);
34            let boxed_stream = stream.write(raw_response.borrow());
35            if boxed_stream.is_ok() {
36                stream.flush().unwrap();
37            };
38            return raw_response;
39        }
40
41        boxed_read.unwrap();
42        let request : &[u8] = &buffer;
43
44        // let raw_request = String::from_utf8(Vec::from(request)).unwrap();
45        // println!("\n\n______{}______\n\n", raw_request);
46
47
48        let boxed_request = Request::parse_request(request);
49        if boxed_request.is_err() {
50            let message = boxed_request.err().unwrap();
51            eprintln!("unable to parse request: {}", &message);
52
53            let raw_response = Server::bad_request_response(message);
54            let boxed_stream = stream.write(raw_response.borrow());
55            if boxed_stream.is_ok() {
56                stream.flush().unwrap();
57            };
58            return raw_response;
59        }
60
61
62        let request: Request = boxed_request.unwrap();
63        let (response, request) = App::handle_request(request);
64
65
66        let log_request_response = Log::request_response(&request, &response, &peer_addr);
67        println!("{}", log_request_response);
68        let raw_response = Response::generate_response(response, request);
69
70        let boxed_stream = stream.write(raw_response.borrow());
71        if boxed_stream.is_ok() {
72            stream.flush().unwrap();
73        };
74
75        raw_response
76    }
77
78    pub fn bad_request_response(message: String) -> Vec<u8> {
79        let error_request = Request {
80            method: METHOD.get.to_string(),
81            request_uri: "".to_string(),
82            http_version: "".to_string(),
83            headers: vec![],
84            body: vec![],
85        };
86
87        let size = message.chars().count() as u64;
88        let content_range = ContentRange {
89            unit: Range::BYTES.to_string(),
90            range: Range { start: 0, end: size },
91            size: size.to_string(),
92            body: Vec::from(message.as_bytes()),
93            content_type: MimeType::TEXT_PLAIN.to_string(),
94        };
95
96        let header_list = Header::get_header_list(&error_request);
97        let error_response: Response = Response::get_response(
98            STATUS_CODE_REASON_PHRASE.n400_bad_request,
99            Some(header_list),
100            Some(vec![content_range])
101        );
102
103        let response = Response::generate_response(error_response, error_request);
104        return response;
105    }
106
107    pub fn process(mut stream: impl Read + Write + Unpin,
108                   connection: ConnectionInfo,
109                   app: impl Application) -> Result<(), String> {
110
111        let request_allocation_size = connection.request_size;
112        let mut buffer = vec![0; request_allocation_size as usize];
113        let boxed_read = stream.read(&mut buffer);
114        if boxed_read.is_err() {
115            let read_message = boxed_read.err().unwrap().to_string();
116            let raw_response = Server::bad_request_response(read_message.clone());
117            let boxed_stream = stream.write(raw_response.borrow());
118            if boxed_stream.is_ok() {
119                stream.flush().unwrap();
120            } else {
121                let write_message = boxed_stream.err().unwrap().to_string();
122                let combined_error = [read_message.clone(), SYMBOL.comma.to_string(), write_message].join(SYMBOL.empty_string);
123                return Err(combined_error);
124            };
125
126            return Err(read_message);
127        }
128
129        boxed_read.unwrap();
130        let request : &[u8] = &buffer;
131
132        // let raw_request = String::from_utf8(Vec::from(request)).unwrap();
133        // println!("\n\n______{}______\n\n", raw_request);
134
135
136        let boxed_request = Request::parse(request);
137        if boxed_request.is_err() {
138            let message = boxed_request.err().unwrap();
139
140            let raw_response = Server::bad_request_response(message.clone());
141            let boxed_stream = stream.write(raw_response.borrow());
142            if boxed_stream.is_ok() {
143                stream.flush().unwrap();
144            } else {
145                let write_message = boxed_stream.err().unwrap().to_string();
146                let combined_error = [message, SYMBOL.comma.to_string(), write_message].join(SYMBOL.empty_string);
147                return Err(combined_error);
148            };
149            return Err(message);
150        }
151
152
153        let request: Request = boxed_request.unwrap();
154
155        let app_processing = app.execute(&request, &connection);
156        if app_processing.is_err() {
157            let message = app_processing.as_ref().err().unwrap().to_string();
158            let response = Server::bad_request_response(message);
159
160            let boxed_stream = stream.write(response.borrow());
161            if boxed_stream.is_ok() {
162                stream.flush().unwrap();
163            } else {
164                let write_message = boxed_stream.err().unwrap().to_string();
165                return Err(write_message);
166            };
167        }
168        let response = app_processing.unwrap();
169
170
171        let client = connection.client;
172        let client_addr = SocketAddr::new(IpAddr::from_str(client.ip.as_str()).unwrap(), client.port as u16);
173        let log_request_response = Log::request_response(&request, &response, &client_addr);
174        println!("{}", log_request_response);
175
176        let raw_response = Response::generate_response(response, request);
177
178        let boxed_stream = stream.write(raw_response.borrow());
179        if boxed_stream.is_ok() {
180            stream.flush().unwrap();
181        } else {
182            let write_message = boxed_stream.err().unwrap().to_string();
183            return Err(write_message);
184        };
185
186        Ok(())
187    }
188
189    pub fn setup() -> Result<(TcpListener, ThreadPool), String> {
190        let info = Log::info("Rust Web Server");
191        println!("{}", info);
192
193        let usage_info = Log::usage_information();
194        println!("{}", usage_info);
195
196
197        println!("RWS Configuration Start: \n");
198
199        set_default_values();
200        bootstrap();
201
202        println!("\nRWS Configuration End\n\n");
203
204
205        let (ip, port, thread_count) = get_ip_port_thread_count();
206
207
208        let mut ip_readable = ip.to_string();
209
210        if ip.contains(":") {
211            ip_readable = [SYMBOL.opening_square_bracket, &ip, SYMBOL.closing_square_bracket].join("");
212        }
213
214        let bind_addr = [ip_readable, SYMBOL.colon.to_string(), port.to_string()].join(SYMBOL.empty_string);
215        println!("Setting up http://{}...", &bind_addr);
216
217        let boxed_listener = TcpListener::bind(&bind_addr);
218        if boxed_listener.is_err() {
219            let message = format!("unable to set up TCP listener: {}", boxed_listener.err().unwrap());
220            return Err(message);
221        }
222
223        let listener = boxed_listener.unwrap();
224        let pool = ThreadPool::new(thread_count as usize);
225
226
227        let server_url_thread_count = Log::server_url_thread_count("http", &bind_addr, thread_count);
228        println!("{}", server_url_thread_count);
229
230        Ok((listener, pool))
231    }
232
233    pub fn run(listener : TcpListener,
234               pool: ThreadPool,
235               app: impl Application + New + Send + 'static + Copy) {
236        for boxed_stream in listener.incoming() {
237            if boxed_stream.is_err() {
238                eprintln!("unable to get TCP stream: {}", boxed_stream.err().unwrap());
239                return;
240            }
241
242            let stream = boxed_stream.unwrap();
243
244            print!("Connection established, ");
245
246            let boxed_local_addr = stream.local_addr();
247            if boxed_local_addr.is_ok() {
248                print!("local addr: {}", boxed_local_addr.unwrap())
249            } else {
250                eprintln!("\nunable to read local addr");
251                return;
252            }
253
254            let boxed_peer_addr = stream.peer_addr();
255            if boxed_peer_addr.is_err() {
256                eprintln!("\nunable to read peer addr");
257                return;
258            }
259            let peer_addr = boxed_peer_addr.unwrap();
260            print!(", peer addr: {}\n", peer_addr.to_string());
261
262            let (server_ip, server_port, _thread_count) = get_ip_port_thread_count();
263            let client_ip = peer_addr.ip().to_string();
264            let client_port = peer_addr.port() as i32;
265            let request_allocation_size = get_request_allocation_size();
266
267            let connection = ConnectionInfo {
268                client: Address {
269                    ip: client_ip.to_string(),
270                    port: client_port
271                },
272                server: Address {
273                    ip: server_ip,
274                    port: server_port
275                },
276                request_size: request_allocation_size,
277            };
278
279
280
281            pool.execute(move || {
282                let boxed_process = Server::process(stream, connection, app);
283                if boxed_process.is_err() {
284                    let message = boxed_process.err().unwrap();
285                    eprintln!("{}", message);
286                }
287            });
288
289        }
290
291
292    }
293
294}
295
296#[derive(Clone)]
297pub struct ConnectionInfo {
298    pub client: Address,
299    pub server: Address,
300    pub request_size: i64
301}
302
303#[derive(Clone)]
304pub struct Address {
305    pub ip: String,
306    pub port: i32
307}
308
309
310