http_type/request/impl.rs
1use crate::*;
2
3impl Default for Request {
4 #[inline]
5 fn default() -> Self {
6 Self {
7 method: Methods::default(),
8 host: String::new(),
9 version: HttpVersion::default(),
10 path: String::new(),
11 querys: RequestQuerys::new(),
12 headers: RequestHeaders::new(),
13 body: Vec::new(),
14 }
15 }
16}
17
18impl Request {
19 /// Creates a new `Request` object from a TCP stream.
20 ///
21 /// # Parameters
22 /// - `reader`: A mut reference to a `&mut BufReader<&mut TcpStream>`
23 ///
24 /// # Returns
25 /// - `Ok`: A `Request` object populated with the HTTP request data.
26 /// - `Err`: An `RequestError` if the request is invalid or cannot be read.
27 #[inline]
28 pub async fn http_from_reader(reader: &mut BufReader<&mut TcpStream>) -> RequestNewResult {
29 let mut request_line: String = String::new();
30 let _ = AsyncBufReadExt::read_line(reader, &mut request_line).await;
31 let parts: Vec<&str> = request_line.split_whitespace().collect();
32 if parts.len() < 3 {
33 return Err(RequestError::InvalidHttpRequest);
34 }
35 let method: RequestMethod = parts[0]
36 .to_string()
37 .parse::<RequestMethod>()
38 .unwrap_or_default();
39 let full_path: RequestPath = parts[1].to_string();
40 let version: RequestVersion = parts[2]
41 .to_string()
42 .parse::<RequestVersion>()
43 .unwrap_or_default();
44 let hash_index: Option<usize> = full_path.find(HASH_SYMBOL);
45 let query_index: Option<usize> = full_path.find(QUERY_SYMBOL);
46 let query_string: String = query_index.map_or(EMPTY_STR.to_owned(), |i| {
47 let temp: String = full_path[i + 1..].to_string();
48 if hash_index.is_none() || hash_index.unwrap() <= i {
49 return temp.into();
50 }
51 let data: String = temp
52 .split(HASH_SYMBOL)
53 .next()
54 .unwrap_or_default()
55 .to_string();
56 data.into()
57 });
58 let querys: RequestQuerys = Self::parse_querys(&query_string);
59 let path: RequestPath = if let Some(i) = query_index.or(hash_index) {
60 full_path[..i].to_string()
61 } else {
62 full_path
63 };
64 let mut headers: RequestHeaders = RequestHeaders::new();
65 let mut host: RequestHost = EMPTY_STR.to_owned();
66 let mut content_length: usize = 0;
67 loop {
68 let mut header_line: String = String::new();
69 let _ = AsyncBufReadExt::read_line(reader, &mut header_line).await;
70 let header_line: &str = header_line.trim();
71 if header_line.is_empty() {
72 break;
73 }
74 let parts: Vec<&str> = header_line.splitn(2, COLON_SPACE_SYMBOL).collect();
75 if parts.len() != 2 {
76 continue;
77 }
78 let key: String = parts[0].trim().to_string();
79 let value: String = parts[1].trim().to_string();
80 if key.eq_ignore_ascii_case(HOST) {
81 host = value.to_string();
82 }
83 if key.eq_ignore_ascii_case(CONTENT_LENGTH) {
84 content_length = value.parse().unwrap_or(0);
85 }
86 headers.insert(key, value);
87 }
88 let mut body: RequestBody = vec![0; content_length];
89 if content_length > 0 {
90 let _ = AsyncReadExt::read_exact(reader, &mut body).await;
91 }
92 Ok(Request {
93 method,
94 host,
95 version,
96 path,
97 querys,
98 headers,
99 body,
100 })
101 }
102
103 /// Creates a new `Request` object from a TCP stream.
104 ///
105 /// # Parameters
106 /// - `stream`: A reference to a `&ArcRwLockStream` representing the incoming connection.
107 ///
108 /// # Returns
109 /// - `Ok`: A `Request` object populated with the HTTP request data.
110 /// - `Err`: An `RequestError` if the request is invalid or cannot be read.
111 #[inline]
112 pub async fn http_request_from_stream(stream: &ArcRwLockStream) -> RequestNewResult {
113 let mut buf_stream: RwLockWriteGuard<'_, TcpStream> = stream.get_write_lock().await;
114 let mut reader: BufReader<&mut TcpStream> = BufReader::new(&mut buf_stream);
115 Self::http_from_reader(&mut reader).await
116 }
117
118 /// Creates a new `Request` object from a TCP stream.
119 ///
120 /// # Parameters
121 /// - `stream`: A reference to a `&ArcRwLockStream` representing the incoming connection.
122 /// - `buffer_size`: Request buffer size
123 ///
124 /// # Returns
125 /// - `Ok`: A `Request` object populated with the HTTP request data.
126 /// - `Err`: An `RequestError` if the request is invalid or cannot be read.
127 #[inline]
128 pub async fn websocket_request_from_stream(
129 stream: &ArcRwLockStream,
130 buffer_size: usize,
131 ) -> RequestNewResult {
132 let mut buf_stream: RwLockWriteGuard<'_, TcpStream> = stream.get_write_lock().await;
133 let mut reader: BufReader<&mut TcpStream> = BufReader::new(&mut buf_stream);
134 Self::websocket_from_reader(&mut reader, buffer_size).await
135 }
136
137 /// Reads a WebSocket request from a TCP stream and constructs a `Request` object.
138 ///
139 /// This function reads data from the provided `BufReader` wrapped around a `TcpStream`.
140 /// It attempts to read up to 1024 bytes into a buffer and constructs a `Request` object
141 /// based on the received data. The request body is set using the received bytes.
142 ///
143 /// # Arguments
144 /// - `reader` - A mutable reference to a `BufReader` wrapping a `TcpStream`.
145 /// This reader is used to read the incoming WebSocket request data.
146 /// - `buffer_size`: - Request buffer size
147 ///
148 /// # Returns
149 /// - `Ok(Request)` - A `Request` object constructed from the received data.
150 /// - If no data is read (`Ok(0)`), an empty `Request` object is returned.
151 /// - If data is successfully read, the request body is set with the received bytes.
152 /// - `Err(RequestError::InvalidWebSocketRequest)` - If an error occurs while reading from the stream.
153 #[inline]
154 pub async fn websocket_from_reader(
155 reader: &mut BufReader<&mut TcpStream>,
156 buffer_size: usize,
157 ) -> RequestNewResult {
158 let mut dynamic_buffer: Vec<u8> = Vec::with_capacity(buffer_size);
159 let mut temp_buffer: Vec<u8> = vec![0; buffer_size];
160 let mut full_frame: Vec<u8> = Vec::with_capacity(buffer_size);
161 loop {
162 let len: usize = match reader.read(&mut temp_buffer).await {
163 Ok(len) => len,
164 Err(_) => return Err(RequestError::InvalidWebSocketRequest),
165 };
166 if len == 0 {
167 break;
168 }
169 dynamic_buffer.extend_from_slice(&temp_buffer[..len]);
170 if let Some((frame, consumed)) =
171 WebSocketFrame::decode_websocket_frame_with_length(&dynamic_buffer)
172 {
173 dynamic_buffer.drain(0..consumed);
174 full_frame.extend_from_slice(frame.get_payload_data());
175 if *frame.get_fin() {
176 let mut request: Request = Request::default();
177 request.set_body(full_frame);
178 return Ok(request);
179 }
180 }
181 }
182 Err(RequestError::InvalidWebSocketRequest)
183 }
184
185 /// Parse querys
186 ///
187 /// # Parameters
188 /// - `query`: &str
189 ///
190 /// # Returns
191 /// - RequestQuerys
192 #[inline]
193 fn parse_querys(query: &str) -> RequestQuerys {
194 let mut query_map: RequestQuerys = RequestQuerys::new();
195 for pair in query.split(AND) {
196 let mut parts: SplitN<'_, &str> = pair.splitn(2, EQUAL);
197 let key: String = parts.next().unwrap_or_default().to_string();
198 let value: String = parts.next().unwrap_or_default().to_string();
199 if !key.is_empty() {
200 query_map.insert(key, value);
201 }
202 }
203 query_map
204 }
205
206 /// Retrieves the value of a query parameter by its key.
207 ///
208 /// # Parameters
209 /// - `key`: The query parameter's key, which can be of any type that implements `Into<RequestQuerysKey>`.
210 ///
211 /// # Returns
212 /// - `Option<RequestQuerysValue>`: Returns `Some(value)` if the key exists in the query parameters,
213 /// or `None` if the key does not exist.
214 #[inline]
215 pub fn get_query<K>(&self, key: K) -> Option<RequestQuerysValue>
216 where
217 K: Into<RequestQuerysKey>,
218 {
219 self.querys
220 .get(&key.into())
221 .and_then(|data| Some(data.clone()))
222 }
223
224 /// Retrieves the value of a request header by its key.
225 ///
226 /// # Parameters
227 /// - `key`: The header's key, which can be of any type that implements `Into<RequestHeadersKey>`.
228 ///
229 /// # Returns
230 /// - `Option<RequestHeadersValue>`: Returns `Some(value)` if the key exists in the request headers,
231 /// or `None` if the key does not exist.
232 #[inline]
233 pub fn get_header<K>(&self, key: K) -> Option<RequestHeadersValue>
234 where
235 K: Into<RequestHeadersKey>,
236 {
237 self.headers
238 .get(&key.into())
239 .and_then(|data| Some(data.clone()))
240 }
241
242 /// Adds a header to the request.
243 ///
244 /// This function inserts a key-value pair into the request headers.
245 /// The key and value are converted into `String`, allowing for efficient handling of both owned and borrowed string data.
246 ///
247 /// # Parameters
248 /// - `key`: The header key, which will be converted into a `String`.
249 /// - `value`: The value of the header, which will be converted into a `String`.
250 ///
251 /// # Returns
252 /// - Returns a mutable reference to the current instance (`&mut Self`), allowing for method chaining.
253 #[inline]
254 pub fn set_header<K, V>(&mut self, key: K, value: V) -> &mut Self
255 where
256 K: Into<String>,
257 V: Into<String>,
258 {
259 self.headers.insert(key.into(), value.into());
260 self
261 }
262
263 /// Set the body of the response.
264 ///
265 /// This method allows you to set the body of the response by converting the provided
266 /// value into a `RequestBody` type. The `body` is updated with the converted value,
267 /// and the method returns a mutable reference to the current instance for method chaining.
268 ///
269 /// # Parameters
270 /// - `body`: The body of the response to be set. It can be any type that can be converted
271 /// into a `RequestBody` using the `Into` trait.
272 ///
273 /// # Return Value
274 /// - Returns a mutable reference to the current instance of the struct, enabling method chaining.
275 /// Set the body of the response.
276 ///
277 /// This method allows you to set the body of the response by converting the provided
278 /// value into a `RequestBody` type. The `body` is updated with the converted value,
279 /// and the method returns a mutable reference to the current instance for method chaining.
280 ///
281 /// # Parameters
282 /// - `body`: The body of the response to be set. It can be any type that can be converted
283 /// into a `RequestBody` using the `Into` trait.
284 ///
285 /// # Return Value
286 /// - Returns a mutable reference to the current instance of the struct, enabling method chaining.
287 #[inline]
288 pub fn set_body<T: Into<RequestBody>>(&mut self, body: T) -> &mut Self {
289 self.body = body.into();
290 self
291 }
292
293 /// Set the HTTP method of the request.
294 ///
295 /// This method allows you to set the HTTP method (e.g., GET, POST) of the request
296 /// by converting the provided value into a `RequestMethod` type. The `method` is updated
297 /// with the converted value, and the method returns a mutable reference to the current
298 /// instance for method chaining.
299 ///
300 /// # Parameters
301 /// - `method`: The HTTP method to be set for the request. It can be any type that can
302 /// be converted into a `RequestMethod` using the `Into` trait.
303 ///
304 /// # Return Value
305 /// - Returns a mutable reference to the current instance of the struct, enabling method chaining.
306 #[inline]
307 pub fn set_method<T: Into<RequestMethod>>(&mut self, method: T) -> &mut Self {
308 self.method = method.into();
309 self
310 }
311
312 /// Set the host of the request.
313 ///
314 /// This method allows you to set the host (e.g., www.example.com) for the request
315 /// by converting the provided value into a `RequestHost` type. The `host` is updated
316 /// with the converted value, and the method returns a mutable reference to the current
317 /// instance for method chaining.
318 ///
319 /// # Parameters
320 /// - `host`: The host to be set for the request. It can be any type that can be converted
321 /// into a `RequestHost` using the `Into` trait.
322 ///
323 /// # Return Value
324 /// - Returns a mutable reference to the current instance of the struct, enabling method chaining.
325 #[inline]
326 pub fn set_host<T: Into<RequestHost>>(&mut self, host: T) -> &mut Self {
327 self.host = host.into();
328 self
329 }
330
331 /// Set the path of the request.
332 ///
333 /// This method allows you to set the path (e.g., /api/v1/resource) for the request
334 /// by converting the provided value into a `RequestPath` type. The `path` is updated
335 /// with the converted value, and the method returns a mutable reference to the current
336 /// instance for method chaining.
337 ///
338 /// # Parameters
339 /// - `path`: The path to be set for the request. It can be any type that can be converted
340 /// into a `RequestPath` using the `Into` trait.
341 ///
342 /// # Return Value
343 /// - Returns a mutable reference to the current instance of the struct, enabling method chaining.
344 #[inline]
345 pub fn set_path<T: Into<RequestPath>>(&mut self, path: T) -> &mut Self {
346 self.path = path.into();
347 self
348 }
349
350 /// Sets a query parameter for the request.
351 ///
352 /// # Parameters
353 /// - `key`: The query parameter's key, which can be of any type that implements `Into<RequestQuerysKey>`.
354 /// - `value`: The query parameter's value, which can be of any type that implements `Into<RequestQuerysValue>`.
355 ///
356 /// # Returns
357 /// - Returns a mutable reference to the current instance (`Self`), allowing for method chaining.
358 #[inline]
359 pub fn set_query<K: Into<RequestQuerysKey>, V: Into<RequestQuerysValue>>(
360 &mut self,
361 key: K,
362 value: V,
363 ) -> &mut Self {
364 self.querys.insert(key.into(), value.into());
365 self
366 }
367
368 /// Converts the request to a formatted string representation.
369 ///
370 /// - Returns: A `String` containing formatted request details.
371 #[inline]
372 pub fn get_string(&self) -> String {
373 let body: &Vec<u8> = self.get_body();
374 format!(
375 "[Request] => [Method]: {}; [Host]: {}; [Version]: {}; [Path]: {}; [Querys]: {:?}; [Headers]: {:?}; [Body]: {};",
376 self.get_method(),
377 self.get_host(),
378 self.get_version(),
379 self.get_path(),
380 self.get_querys(),
381 self.get_headers(),
382 body_to_string(body),
383 )
384 }
385
386 /// Retrieves the upgrade type from the request headers.
387 ///
388 /// - Returns: The `UpgradeType` extracted from the `UPGRADE` header.
389 /// If the header is missing or invalid, returns the default `UpgradeType`.
390 #[inline]
391 pub fn get_upgrade_type(&self) -> UpgradeType {
392 let upgrade_type: UpgradeType = self
393 .get_header(UPGRADE)
394 .and_then(|data| data.parse::<UpgradeType>().ok())
395 .unwrap_or_default();
396 upgrade_type
397 }
398}