http_server_rs/
httpreader.rs1use std::{collections::BTreeMap, io::{Error, Read, Write}, net::{SocketAddr, TcpStream}, time::Duration};
2use crate::httperror::*;
3
4use crate::{httpconstants::HttpConstants, httperror::HttpErrorWrapper};
5
6pub struct HttpReader {
7 req_method : String,
8 req_path : String,
9 req_protocol : String,
10 req_headers : BTreeMap<String, String>,
11 req_lines : BTreeMap<i32, String>,
12 req_body : BTreeMap<i32, u8>,
13 response_headers : BTreeMap<String, String>,
14 sent_headers : bool,
15 tcpstream : TcpStream,
16 max_client_timeout_ms : u64,
17}
18
19#[allow(dead_code)]
20impl HttpReader {
21 pub fn new(tcpstream : TcpStream, max_client_timeout_ms : u64) -> Result<HttpReader, HttpErrorWrapper> {
22 let mut this = HttpReader {
23 req_method: String::from(""),
24 req_path : String::from(""),
25 req_protocol : String::from(""),
26 req_headers : BTreeMap::new(),
27 req_lines : BTreeMap::new(),
28 req_body : BTreeMap::new(),
29 response_headers : BTreeMap::new(),
30 sent_headers : false,
31 tcpstream,
32 max_client_timeout_ms,
33 };
34 let result = this.read_lines();
35 if result.is_some() {
36 return Result::Err(result.unwrap());
37 } else {
38 return Result::Ok(this);
39 }
40
41 }
42
43 fn read_lines(&mut self) -> Option<HttpErrorWrapper> {
44
45 let mut had_first_line = false;
46 let mut current_str : Vec<u8> = Vec::new();
47 let mut index = 0;
48 let mut buf = [0u8];
49 let stream = &mut self.tcpstream;
50 stream.set_read_timeout(Some(Duration::from_millis(self.max_client_timeout_ms))).unwrap();
51 loop {
52
53 let result = stream.read(&mut buf);
54 if result.is_err() {
55 return Option::Some(INCOMPLETE_REQUEST.to_wrapped_respond(stream));
56 } else if result.unwrap() == 0 {
57 return Option::Some(CLIENT_TIMEOUT.to_wrapped_respond(stream));
58 }
59
60 let character = buf[0];
61 current_str.push(character);
62 if character as char != '\n' {
63 continue;
64 }
65
66 if current_str.len() == 2 {current_str.clear();
68 if !had_first_line {
69 continue;
70 } else {
71 break;
72 }
73 } else {
74 let str = String::from_utf8_lossy(current_str.clone().as_slice()).to_string();
75 self.req_lines.insert(index, str);
76 index = index + 1;
77 current_str.clear();
78 had_first_line = true;
79 }
80
81 }
82
83 let mut start_line_iterator = self.req_lines.get(&0).unwrap().split_whitespace();
84 let mut had_request_error = false;
85 let method = start_line_iterator.next();
86 if method.is_none() {
87 had_request_error = true;
88 } else {
89 self.req_method = method.unwrap().to_string();
90 }
91 let path = start_line_iterator.next();
92 if path.is_none() {
93 had_request_error = true;
94 } else {
95 self.req_path = path.unwrap().to_string();
96 }
97 let protocol = start_line_iterator.next();
98 if protocol.is_none() {
99 had_request_error = true;
100 } else {
101 self.req_protocol = protocol.unwrap().to_string();
102 }
103 if had_request_error {
104 return Option::Some(BAD_REQUEST_LINE.to_wrapped_respond(stream));
105 }
106
107 let mut i = 1;
108 let len = self.req_lines.len();
109 while i < len {
110 let unsafe_header = self.req_lines.get(&(i as i32))
111 .unwrap()
112 .split_once(": ");
113 if unsafe_header.is_none() {
114 return Option::Some(INCORRECT_HEADER_FORMAT.to_wrapped_respond(stream));
115 }
116 let header = unsafe_header
117 .unwrap();
118
119 let key = header.0;
120
121 let value = header.1;
122 let value = value.split_at(value.len() - 2).0; self.req_headers.insert(key.to_string().to_lowercase(), value.to_string());
125 i += 1;
126 }
127
128 let content_length = self.req_headers.get("content-length");
129 if content_length.is_some() {
130 let unwrapped_length = content_length.unwrap();
131 let parsed = usize::from_str_radix(unwrapped_length, 10);
132 if parsed.is_err() { return Option::Some(INCORRECT_CONTENT_LENGTH.to_wrapped_respond(stream));
134 }
135 let amount_to_read = parsed.unwrap();
136 if amount_to_read != 0 {
137 let mut buf: Vec<u8> = Vec::new();
138 buf.resize(amount_to_read, 0);
139 let buf = buf.as_mut_slice();
140
141 let result = stream.read(buf);
142
143 if result.is_err() || result.unwrap() != amount_to_read {
144 return Option::Some(INCOMPLETE_BODY.to_wrapped_respond(stream));
145 }
146
147 for i in 0..amount_to_read {
148 self.req_body.insert(i as i32, *buf.get(i).unwrap());
149 }
150 }
151 }
152
153 let _body = String::from_utf8_lossy(self.get_request_body().as_slice()).to_string();
154
155 return Option::None;
156
157 }
158
159 pub fn get_peer_address(&self) -> Result<SocketAddr, Error> {
160 return self.tcpstream.peer_addr();
161 }
162
163 pub fn get_local_address(&self) -> Result<SocketAddr, Error> {
164 return self.tcpstream.local_addr();
165 }
166
167 pub fn borrow_stream(&mut self) -> &mut TcpStream {
168 return &mut self.tcpstream;
169 }
170
171 pub fn consume_stream(self) -> TcpStream {
172 return self.tcpstream;
173 }
174
175 pub fn respond_404(&self) {
176 ENDPOINT_NOT_FOUND.to_wrapped_respond(&self.tcpstream);
177 }
178
179 pub fn get_request_method(&self) -> String {
181 return self.req_method.to_string();
182 }
183
184 pub fn get_request_path(&self) -> String {
185 return self.req_path.to_string();
186 }
187
188 pub fn get_request_protocol(&self) -> String {
189 return self.req_protocol.to_string();
190 }
191
192 pub fn get_request_headers(&mut self) -> &mut BTreeMap<String, String> {
193 return &mut self.req_headers;
194 }
195
196 pub fn get_request_body(&self) -> Vec<u8> {
197 return self.req_body.values().cloned().collect();
198 }
199
200 pub fn get_response_headers(&mut self) -> &mut BTreeMap<String, String> {
202 return &mut self.response_headers;
203 }
204
205 pub fn add_cross_origin_resource_sharing_headers(&mut self) {
206 let response = self.get_response_headers();
207 response.insert(String::from("Access-Control-Allow-Origin"), String::from("*"));
208 response.insert(String::from("Access-Control-Allow-Headers"), String::from("Origin, X-Requested-With, Content-Type, Accept, Authorization"));
209 response.insert(String::from("Access-Control-Allow-Methods"), String::from("GET, OPTIONS, HEAD, PUT, POST"));
210 response.insert(String::from("Access-Control-Allow-Credentials"), String::from("true"));
211 }
212
213 pub fn write_response_headers(&mut self, response_code : i32, body_length : usize) -> Result<usize, Error> {
214
215 if self.sent_headers {
216 return Ok(0);
217 }
218
219 let start_line = "HTTP/1.1 ".to_owned() + response_code.to_string().as_str() + HttpConstants::get_code_text(response_code) + "\r\n";
220
221 let response_headers = self.get_response_headers();
222 response_headers.insert("Content-Length".to_string(), body_length.to_string());
223 response_headers.insert("Date".to_string(), HttpConstants::get_current_formatted_date());
224
225 let mut response_bytes : Vec<u8> = Vec::new();
226 response_bytes.append(&mut start_line.clone().into_bytes());
227 for entry in response_headers {
228 response_bytes.append(&mut entry.0.clone().into_bytes());
229 response_bytes.append(&mut ": ".to_string().into_bytes());
230 response_bytes.append(&mut entry.1.clone().into_bytes());
231 response_bytes.append(&mut "\r\n".to_string().into_bytes());
232 }
233 response_bytes.append(&mut "\r\n".to_string().into_bytes());
234
235 let result = self.tcpstream.write(response_bytes.as_mut_slice());
236
237 self.sent_headers = true;
238
239 return result;
240 }
241
242 pub fn write_response_body(&mut self, body : &[u8]) -> Result<usize, Error> {
243 return self.tcpstream.write(body);
244 }
245
246 pub fn get_tcpstream(&mut self) -> &mut TcpStream {
247 return &mut self.tcpstream;
248 }
249
250}