rust_web_server/server/
mod.rs1#[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 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 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