http_type/request/impl.rs
1use crate::*;
2
3/// Provides a default value for `Request`.
4///
5/// Returns a new `Request` instance with all fields initialized to their default values.
6impl Default for Request {
7 fn default() -> Self {
8 Self {
9 method: Method::default(),
10 host: String::new(),
11 version: HttpVersion::default(),
12 path: String::new(),
13 querys: hash_map_xx_hash3_64(),
14 headers: hash_map_xx_hash3_64(),
15 body: Vec::new(),
16 }
17 }
18}
19
20impl Request {
21 /// Creates a new instance of `Request`.
22 ///
23 /// # Returns
24 ///
25 /// - `Request` - A new request instance with default values.
26 #[inline]
27 pub fn new() -> Self {
28 Self::default()
29 }
30
31 /// Parses an HTTP request from a buffered TCP stream reader.
32 ///
33 /// Reads request line, headers and body from the stream and constructs a Request object.
34 ///
35 /// # Arguments
36 ///
37 /// - `&mut BufReader<&mut TcpStream>` - The buffered TCP stream reader.
38 /// - `usize` - The buffer size for reading.
39 ///
40 /// # Returns
41 ///
42 /// - `Result<Request, RequestError>` - The parsed request or an error.
43 pub async fn http_from_reader(
44 reader: &mut BufReader<&mut TcpStream>,
45 buffer: usize,
46 ) -> RequestReaderHandleResult {
47 let mut request_line: String = String::with_capacity(buffer.min(8192));
48 let _ = AsyncBufReadExt::read_line(reader, &mut request_line).await;
49 let parts: Vec<&str> = request_line.split_whitespace().collect();
50 let parts_len: usize = parts.len();
51 if parts_len < 3 {
52 return Err(RequestError::InvalidHttpRequestPartsLength(parts_len));
53 }
54 let method: RequestMethod = parts[0].parse::<RequestMethod>().unwrap_or_default();
55 let full_path: RequestPath = parts[1].to_string();
56 let version: RequestVersion = parts[2].parse::<RequestVersion>().unwrap_or_default();
57 let hash_index: OptionUsize = full_path.find(HASH);
58 let query_index: OptionUsize = full_path.find(QUERY);
59 let query_string: String = query_index.map_or_else(
60 || String::new(),
61 |i| {
62 let temp: &str = &full_path[i + 1..];
63 if hash_index.is_none() || hash_index.unwrap() <= i {
64 return temp.to_owned();
65 }
66 temp.split(HASH).next().unwrap_or_default().to_owned()
67 },
68 );
69 let querys: RequestQuerys = Self::parse_querys(&query_string);
70 let path: RequestPath = if let Some(i) = query_index.or(hash_index) {
71 full_path[..i].to_owned()
72 } else {
73 full_path.to_owned()
74 };
75 let mut headers: RequestHeaders = hash_map_xx_hash3_64();
76 let mut host: RequestHost = String::new();
77 let mut content_length: usize = 0;
78 loop {
79 let mut header_line: String = String::with_capacity(buffer.min(DEFAULT_BUFFER_SIZE));
80 let _ = AsyncBufReadExt::read_line(reader, &mut header_line).await;
81 let header_line: &str = header_line.trim();
82 if header_line.is_empty() {
83 break;
84 }
85 if let Some((key_part, value_part)) = header_line.split_once(COLON) {
86 let key: String = key_part.trim().to_ascii_lowercase();
87 if key.is_empty() {
88 continue;
89 }
90 let value: String = value_part.trim().to_string();
91 if key == HOST {
92 host = value.clone();
93 } else if key == CONTENT_LENGTH {
94 content_length = value.parse().unwrap_or(0);
95 }
96 headers.entry(key).or_default().push_back(value);
97 }
98 }
99 let mut body: RequestBody = vec![0; content_length];
100 if content_length > 0 {
101 let _ = AsyncReadExt::read_exact(reader, &mut body).await;
102 }
103 Ok(Request {
104 method,
105 host,
106 version,
107 path,
108 querys,
109 headers,
110 body,
111 })
112 }
113
114 /// Parses an HTTP request from a TCP stream.
115 ///
116 /// Wraps the stream in a buffered reader and delegates to `http_from_reader`.
117 ///
118 /// # Arguments
119 ///
120 /// - `&ArcRwLock<TcpStream>` - The TCP stream to read from.
121 /// - `usize` - The buffer size for reading.
122 ///
123 /// # Returns
124 ///
125 /// - `Result<Request, RequestError>` - The parsed request or an error.
126 pub async fn http_from_stream(
127 stream: &ArcRwLockStream,
128 buffer: usize,
129 ) -> RequestReaderHandleResult {
130 let mut buf_stream: RwLockWriteGuard<'_, TcpStream> = stream.write().await;
131 let mut reader: BufReader<&mut TcpStream> = BufReader::new(&mut buf_stream);
132 Self::http_from_reader(&mut reader, buffer).await
133 }
134
135 /// Parses a WebSocket request from a TCP stream.
136 ///
137 /// Wraps the stream in a buffered reader and delegates to `ws_from_reader`.
138 ///
139 /// # Arguments
140 ///
141 /// - `&ArcRwLock<TcpStream>` - The TCP stream to read from.
142 /// - `usize` - The buffer size for reading.
143 /// - `&mut Request` - The request template to populate.
144 ///
145 /// # Returns
146 ///
147 /// - `Result<Request, RequestError>` - The parsed WebSocket request or an error.
148 pub async fn ws_from_stream(
149 stream: &ArcRwLockStream,
150 buffer: usize,
151 request: &mut Self,
152 ) -> RequestReaderHandleResult {
153 let mut buf_stream: RwLockWriteGuard<'_, TcpStream> = stream.write().await;
154 let mut reader: BufReader<&mut TcpStream> = BufReader::new(&mut buf_stream);
155 Self::ws_from_reader(&mut reader, buffer, request).await
156 }
157
158 /// Parses a WebSocket request from a buffered TCP stream.
159 ///
160 /// Handles WebSocket frames including text, binary, ping, pong and close frames.
161 /// Assembles the request body from frame payload data.
162 ///
163 /// # Arguments
164 ///
165 /// - `&mut BufReader<&mut TcpStream>` - The buffered TCP stream reader.
166 /// - `usize` - The buffer size for reading frames.
167 /// - `&mut Request` - The request template to populate.
168 ///
169 /// # Returns
170 ///
171 /// - `Result<Request, RequestError>` - The parsed WebSocket request or an error.
172 pub async fn ws_from_reader(
173 reader: &mut BufReader<&mut TcpStream>,
174 buffer: usize,
175 request: &mut Self,
176 ) -> RequestReaderHandleResult {
177 let mut dynamic_buffer: Vec<u8> = Vec::with_capacity(buffer.min(DEFAULT_BUFFER_SIZE));
178 let temp_buffer_size: usize = buffer.min(DEFAULT_BUFFER_SIZE);
179 let mut temp_buffer: Vec<u8> = vec![0; temp_buffer_size];
180 let mut full_frame: Vec<u8> = Vec::with_capacity(buffer.min(DEFAULT_BUFFER_SIZE));
181 let mut error_handle = || {
182 request.body.clear();
183 };
184 loop {
185 let len: usize = match reader.read(&mut temp_buffer).await {
186 Ok(len) => len,
187 Err(err) => {
188 error_handle();
189 if err.kind() == ErrorKind::ConnectionReset
190 || err.kind() == ErrorKind::ConnectionAborted
191 {
192 return Err(RequestError::ClientDisconnected);
193 }
194 return Err(RequestError::InvalidWebSocketRequest(err.to_string()));
195 }
196 };
197 if len == 0 {
198 error_handle();
199 return Err(RequestError::IncompleteWebSocketFrame);
200 }
201 dynamic_buffer.extend_from_slice(&temp_buffer[..len]);
202 while let Some((frame, consumed)) = WebSocketFrame::decode_ws_frame(&dynamic_buffer) {
203 dynamic_buffer.drain(0..consumed);
204 match frame.get_opcode() {
205 WebSocketOpcode::Close => {
206 error_handle();
207 return Err(RequestError::ClientClosedConnection);
208 }
209 WebSocketOpcode::Ping | WebSocketOpcode::Pong => {
210 continue;
211 }
212 WebSocketOpcode::Text | WebSocketOpcode::Binary => {
213 full_frame.extend_from_slice(frame.get_payload_data());
214 if *frame.get_fin() {
215 let mut request: Request = request.clone();
216 request.body = full_frame;
217 return Ok(request);
218 }
219 }
220 _ => {
221 error_handle();
222 return Err(RequestError::InvalidWebSocketFrame(
223 "Unsupported opcode".to_owned(),
224 ));
225 }
226 }
227 }
228 }
229 }
230
231 /// Parses a query string as_ref key-value pairs.
232 ///
233 /// Expects format "key1=value1&key2=value2". Empty values are allowed.
234 ///
235 /// # Arguments
236 ///
237 /// - `&str` - The query string to parse.
238 ///
239 /// # Returns
240 ///
241 /// - `HashMap<String, String>` - The parsed query parameters.
242 fn parse_querys<Q>(query: Q) -> RequestQuerys
243 where
244 Q: AsRef<str>,
245 {
246 let mut query_map: RequestQuerys = hash_map_xx_hash3_64();
247 for pair in query.as_ref().split(AND) {
248 if let Some((key, value)) = pair.split_once(EQUAL) {
249 if !key.is_empty() {
250 query_map.insert(key.to_string(), value.to_string());
251 }
252 } else if !pair.is_empty() {
253 query_map.insert(pair.to_string(), String::new());
254 }
255 }
256 query_map
257 }
258
259 /// Gets a query parameter value by key.
260 ///
261 /// The key type must implement AsRef<str> conversion.
262 ///
263 /// # Arguments
264 ///
265 /// - `AsRef<str>` - The query parameter key (implements AsRef<str>).
266 ///
267 /// # Returns
268 ///
269 /// - `Option<String>` - The parameter value if exists.
270 #[inline]
271 pub fn try_get_query<K>(&self, key: K) -> OptionRequestQuerysValue
272 where
273 K: AsRef<str>,
274 {
275 self.querys.get(key.as_ref()).cloned()
276 }
277
278 /// Retrieves the value of a request header by its key.
279 ///
280 /// # Arguments
281 ///
282 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
283 ///
284 /// # Returns
285 ///
286 /// - `OptionRequestHeadersValue` - The optional header values.
287 #[inline]
288 pub fn try_get_header<K>(&self, key: K) -> OptionRequestHeadersValue
289 where
290 K: AsRef<str>,
291 {
292 self.headers.get(key.as_ref()).cloned()
293 }
294
295 /// Retrieves the first value of a request header by its key.
296 ///
297 /// # Arguments
298 ///
299 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
300 ///
301 /// # Returns
302 ///
303 /// - `OptionRequestHeadersValueItem` - The first header value if exists.
304 #[inline]
305 pub fn try_get_header_front<K>(&self, key: K) -> OptionRequestHeadersValueItem
306 where
307 K: AsRef<str>,
308 {
309 self.headers
310 .get(key.as_ref())
311 .and_then(|values| values.front().cloned())
312 }
313
314 /// Retrieves the last value of a request header by its key.
315 ///
316 /// # Arguments
317 ///
318 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
319 ///
320 /// # Returns
321 ///
322 /// - `OptionRequestHeadersValueItem` - The last header value if exists.
323 #[inline]
324 pub fn try_get_header_back<K>(&self, key: K) -> OptionRequestHeadersValueItem
325 where
326 K: AsRef<str>,
327 {
328 self.headers
329 .get(key.as_ref())
330 .and_then(|values| values.back().cloned())
331 }
332
333 /// Retrieves the number of values for a specific header.
334 ///
335 /// # Arguments
336 ///
337 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
338 ///
339 /// # Returns
340 ///
341 /// - `usize` - The count of values for the header.
342 #[inline]
343 pub fn get_header_length<K>(&self, key: K) -> usize
344 where
345 K: AsRef<str>,
346 {
347 self.headers
348 .get(key.as_ref())
349 .map(|values| values.len())
350 .unwrap_or(0)
351 }
352
353 /// Retrieves the total number of header values across all headers.
354 ///
355 /// # Returns
356 ///
357 /// - `usize` - The total count of all header values.
358 #[inline]
359 pub fn get_headers_values_length(&self) -> usize {
360 self.headers.values().map(|values| values.len()).sum()
361 }
362
363 /// Retrieves the number of unique headers.
364 ///
365 /// # Returns
366 ///
367 /// - `usize` - The count of unique header keys.
368 #[inline]
369 pub fn get_headers_length(&self) -> usize {
370 self.headers.len()
371 }
372
373 /// Checks if a specific header exists.
374 ///
375 /// # Arguments
376 ///
377 /// - `AsRef<str>` - The header key to check (must implement AsRef<str>).
378 ///
379 /// # Returns
380 ///
381 /// - `bool` - Whether the header exists.
382 #[inline]
383 pub fn has_header<K>(&self, key: K) -> bool
384 where
385 K: AsRef<str>,
386 {
387 self.headers.contains_key(key.as_ref())
388 }
389
390 /// Checks if a header contains a specific value.
391 ///
392 /// # Arguments
393 ///
394 /// - `AsRef<str>` - The header key to check (must implement AsRef<str>).
395 /// - `AsRef<str>` - The value to search for (must implement AsRef<str>).
396 ///
397 /// # Returns
398 ///
399 /// - `bool` - Whether the header contains the value.
400 #[inline]
401 pub fn has_header_value<K, V>(&self, key: K, value: V) -> bool
402 where
403 K: AsRef<str>,
404 V: AsRef<str>,
405 {
406 if let Some(values) = self.headers.get(key.as_ref()) {
407 values.contains(&value.as_ref().to_owned())
408 } else {
409 false
410 }
411 }
412
413 /// Retrieves the body content of the request as a UTF-8 encoded string.
414 ///
415 /// This method uses `String::from_utf8_lossy` to convert the byte slice returned by `self.get_body()` as_ref a string.
416 /// If the byte slice contains invalid UTF-8 sequences, they will be replaced with the Unicode replacement character ().
417 ///
418 /// # Returns
419 ///
420 /// - `String` - The body content as a string.
421 #[inline]
422 pub fn get_body_string(&self) -> String {
423 String::from_utf8_lossy(self.get_body()).into_owned()
424 }
425
426 /// Deserializes the body content of the request as_ref a specified type `T`.
427 ///
428 /// This method first retrieves the body content as a byte slice using `self.get_body()`.
429 /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
430 ///
431 /// # Arguments
432 ///
433 /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
434 ///
435 /// # Returns
436 ///
437 /// - `ResultJsonError<T>` - The deserialization result.
438 pub fn get_body_json<T>(&self) -> ResultJsonError<T>
439 where
440 T: DeserializeOwned,
441 {
442 json_from_slice(self.get_body())
443 }
444
445 /// Converts the request to a formatted string representation.
446 ///
447 /// This method provides a human-readable summary of the request, including its method,
448 /// host, version, path, query parameters, headers, and body information.
449 ///
450 /// # Returns
451 ///
452 /// - `String` - The formatted request details.
453 #[inline]
454 pub fn get_string(&self) -> String {
455 let body: &Vec<u8> = self.get_body();
456 let body_type: &'static str = if std::str::from_utf8(body).is_ok() {
457 PLAIN
458 } else {
459 BINARY
460 };
461 format!(
462 "[Request] => [method]: {}; [host]: {}; [version]: {}; [path]: {}; [querys]: {:?}; [headers]: {:?}; [body]: {} bytes {};",
463 self.get_method(),
464 self.get_host(),
465 self.get_version(),
466 self.get_path(),
467 self.get_querys(),
468 self.get_headers(),
469 body.len(),
470 body_type
471 )
472 }
473
474 /// Retrieves the upgrade type from the request headers.
475 ///
476 /// This method looks for the `UPGRADE` header and attempts to parse its value
477 /// as_ref an `UpgradeType`. If the header is missing or the value is invalid,
478 /// it returns the default `UpgradeType`.
479 ///
480 /// # Returns
481 ///
482 /// - `UpgradeType` - The parsed upgrade type.
483 #[inline]
484 pub fn get_upgrade_type(&self) -> UpgradeType {
485 let upgrade_type: UpgradeType = self
486 .try_get_header_back(UPGRADE)
487 .and_then(|data| data.parse::<UpgradeType>().ok())
488 .unwrap_or_default();
489 upgrade_type
490 }
491
492 /// Checks whether the WebSocket upgrade is enabled for this request.
493 ///
494 /// This method determines if the `UPGRADE` header indicates a WebSocket connection.
495 ///
496 /// # Returns
497 ///
498 /// - `bool` - Whether WebSocket upgrade is enabled.
499 #[inline]
500 pub fn is_ws(&self) -> bool {
501 self.get_upgrade_type().is_ws()
502 }
503
504 /// Checks if the current upgrade type is HTTP/2 cleartext (h2c).
505 ///
506 /// # Returns
507 ///
508 /// - `bool` - Whether the upgrade type is h2c.
509 #[inline]
510 pub fn is_h2c(&self) -> bool {
511 self.get_upgrade_type().is_h2c()
512 }
513
514 /// Checks if the current upgrade type is TLS (any version).
515 ///
516 /// # Returns
517 ///
518 /// - `bool` - Whether the upgrade type is TLS.
519 #[inline]
520 pub fn is_tls(&self) -> bool {
521 self.get_upgrade_type().is_tls()
522 }
523
524 /// Checks whether the upgrade type is unknown.
525 ///
526 /// # Returns
527 ///
528 /// - `bool` - Whether the upgrade type is unknown.
529 #[inline]
530 pub fn is_unknown_upgrade(&self) -> bool {
531 self.get_upgrade_type().is_unknown()
532 }
533
534 /// Checks if the HTTP version is HTTP/1.1 or higher.
535 ///
536 /// # Returns
537 ///
538 /// - `bool` - Whether the version is HTTP/1.1 or higher.
539 #[inline]
540 pub fn is_http1_1_or_higher(&self) -> bool {
541 self.get_version().is_http1_1_or_higher()
542 }
543
544 /// Checks whether the HTTP version is HTTP/0.9.
545 ///
546 /// # Returns
547 ///
548 /// - `bool` - Whether the version is HTTP/0.9.
549 #[inline]
550 pub fn is_http0_9(&self) -> bool {
551 self.get_version().is_http0_9()
552 }
553
554 /// Checks whether the HTTP version is HTTP/1.0.
555 ///
556 /// # Returns
557 ///
558 /// - `bool` - Whether the version is HTTP/1.0.
559 #[inline]
560 pub fn is_http1_0(&self) -> bool {
561 self.get_version().is_http1_0()
562 }
563
564 /// Checks whether the HTTP version is HTTP/1.1.
565 ///
566 /// # Returns
567 ///
568 /// - `bool` - Whether the version is HTTP/1.1.
569 #[inline]
570 pub fn is_http1_1(&self) -> bool {
571 self.get_version().is_http1_1()
572 }
573
574 /// Checks whether the HTTP version is HTTP/2.
575 ///
576 /// # Returns
577 ///
578 /// - `bool` - Whether the version is HTTP/2.
579 #[inline]
580 pub fn is_http2(&self) -> bool {
581 self.get_version().is_http2()
582 }
583
584 /// Checks whether the HTTP version is HTTP/3.
585 ///
586 /// # Returns
587 ///
588 /// - `bool` - Whether the version is HTTP/3.
589 #[inline]
590 pub fn is_http3(&self) -> bool {
591 self.get_version().is_http3()
592 }
593
594 /// Checks whether the HTTP version is unknown.
595 ///
596 /// # Returns
597 ///
598 /// - `bool` - Whether the version is unknown.
599 #[inline]
600 pub fn is_unknown_version(&self) -> bool {
601 self.get_version().is_unknown()
602 }
603
604 /// Checks whether the version belongs to the HTTP family.
605 ///
606 /// # Returns
607 ///
608 /// - `bool` - Whether the version is HTTP.
609 #[inline]
610 pub fn is_http(&self) -> bool {
611 self.get_version().is_http()
612 }
613
614 /// Checks whether the request method is GET.
615 ///
616 /// # Returns
617 ///
618 /// - `bool` - Whether the method is GET.
619 #[inline]
620 pub fn is_get(&self) -> bool {
621 self.get_method().is_get()
622 }
623
624 /// Checks whether the request method is POST.
625 ///
626 /// # Returns
627 ///
628 /// - `bool` - Whether the method is POST.
629 #[inline]
630 pub fn is_post(&self) -> bool {
631 self.get_method().is_post()
632 }
633
634 /// Checks whether the request method is PUT.
635 ///
636 /// # Returns
637 ///
638 /// - `bool` - Whether the method is PUT.
639 #[inline]
640 pub fn is_put(&self) -> bool {
641 self.get_method().is_put()
642 }
643
644 /// Checks whether the request method is DELETE.
645 ///
646 /// # Returns
647 ///
648 /// - `bool` - Whether the method is DELETE.
649 #[inline]
650 pub fn is_delete(&self) -> bool {
651 self.get_method().is_delete()
652 }
653
654 /// Checks whether the request method is PATCH.
655 ///
656 /// # Returns
657 ///
658 /// - `bool` - Whether the method is PATCH.
659 #[inline]
660 pub fn is_patch(&self) -> bool {
661 self.get_method().is_patch()
662 }
663
664 /// Checks whether the request method is HEAD.
665 ///
666 /// # Returns
667 ///
668 /// - `bool` - Whether the method is HEAD.
669 #[inline]
670 pub fn is_head(&self) -> bool {
671 self.get_method().is_head()
672 }
673
674 /// Checks whether the request method is OPTIONS.
675 ///
676 /// # Returns
677 ///
678 /// - `bool` - Whether the method is OPTIONS.
679 #[inline]
680 pub fn is_options(&self) -> bool {
681 self.get_method().is_options()
682 }
683
684 /// Checks whether the request method is CONNECT.
685 ///
686 /// # Returns
687 ///
688 /// - `bool` - Whether the method is CONNECT.
689 #[inline]
690 pub fn is_connect(&self) -> bool {
691 self.get_method().is_connect()
692 }
693
694 /// Checks whether the request method is TRACE.
695 ///
696 /// # Returns
697 ///
698 /// - `bool` - Whether the method is TRACE.
699 #[inline]
700 pub fn is_trace(&self) -> bool {
701 self.get_method().is_trace()
702 }
703
704 /// Checks whether the request method is UNKNOWN.
705 ///
706 /// # Returns
707 ///
708 /// - `bool` - Whether the method is UNKNOWN.
709 #[inline]
710 pub fn is_unknown_method(&self) -> bool {
711 self.get_method().is_unknown()
712 }
713
714 /// Determines if a keep-alive connection should be enabled for this request.
715 ///
716 /// This function checks the `Connection` header and the HTTP version to determine
717 /// if keep-alive should be enabled. The logic is as follows:
718 ///
719 /// 1. If the `Connection` header exists:
720 /// - Returns `true` if the header value is "keep-alive" (case-insensitive).
721 /// - Returns `false` if the header value is "close" (case-insensitive).
722 /// 2. If no `Connection` header is present:
723 /// - Returns `true` if the HTTP version is 1.1 or higher.
724 /// - Returns `false` otherwise.
725 ///
726 /// # Returns
727 ///
728 /// - `bool` - Whether keep-alive should be enabled.
729 #[inline]
730 pub fn is_enable_keep_alive(&self) -> bool {
731 if let Some(connection_value) = self.try_get_header_back(CONNECTION) {
732 if connection_value.eq_ignore_ascii_case(KEEP_ALIVE) {
733 return true;
734 } else if connection_value.eq_ignore_ascii_case(CLOSE) {
735 return self.is_ws();
736 }
737 }
738 self.is_http1_1_or_higher() || self.is_ws()
739 }
740
741 /// Determines if keep-alive should be disabled for this request.
742 ///
743 /// # Returns
744 ///
745 /// - `bool` - Whether keep-alive should be disabled.
746 #[inline]
747 pub fn is_disable_keep_alive(&self) -> bool {
748 !self.is_enable_keep_alive()
749 }
750}