http_type/request/impl.rs
1use crate::*;
2
3/// Implements the `std::error::Error` trait for `RequestError`.
4impl std::error::Error for RequestError {}
5
6/// Provides a default value for `RequestError`.
7impl Default for RequestError {
8 /// Provides a default value for `RequestError`.
9 ///
10 /// Returns a `RequestError::Unknown` with `HttpStatus::InternalServerError`.
11 #[inline(always)]
12 fn default() -> Self {
13 RequestError::Unknown(HttpStatus::InternalServerError)
14 }
15}
16
17impl RequestError {
18 /// Gets the HTTP status associated with this error.
19 ///
20 /// Returns the HttpStatus enum variant that corresponds to this error.
21 ///
22 /// # Arguments
23 ///
24 /// - `&self` - The RequestError instance.
25 ///
26 /// # Returns
27 ///
28 /// - `HttpStatus` - The HTTP status associated with this error.
29 pub fn get_http_status(&self) -> HttpStatus {
30 match self {
31 Self::HttpRead(status) => *status,
32 Self::GetTcpStream(status) => *status,
33 Self::GetTlsStream(status) => *status,
34 Self::ReadConnection(status) => *status,
35 Self::RequestAborted(status) => *status,
36 Self::TlsStreamConnect(status) => *status,
37 Self::NeedOpenRedirect(status) => *status,
38 Self::MaxRedirectTimes(status) => *status,
39 Self::MethodsNotSupport(status) => *status,
40 Self::RedirectInvalidUrl(status) => *status,
41 Self::ClientDisconnected(status) => *status,
42 Self::RedirectUrlDeadLoop(status) => *status,
43 Self::ClientClosedConnection(status) => *status,
44 Self::IncompleteWebSocketFrame(status) => *status,
45 Self::RequestTooLong(status) => *status,
46 Self::PathTooLong(status) => *status,
47 Self::QueryTooLong(status) => *status,
48 Self::HeaderLineTooLong(status) => *status,
49 Self::TooManyHeaders(status) => *status,
50 Self::HeaderKeyTooLong(status) => *status,
51 Self::HeaderValueTooLong(status) => *status,
52 Self::ContentLengthTooLarge(status) => *status,
53 Self::InvalidContentLength(status) => *status,
54 Self::InvalidUrlScheme(status) => *status,
55 Self::InvalidUrlHost(status) => *status,
56 Self::InvalidUrlPort(status) => *status,
57 Self::InvalidUrlPath(status) => *status,
58 Self::InvalidUrlQuery(status) => *status,
59 Self::InvalidUrlFragment(status) => *status,
60 Self::ReadTimeout(status) => *status,
61 Self::WriteTimeout(status) => *status,
62 Self::TcpConnectionFailed(status) => *status,
63 Self::TlsHandshakeFailed(status) => *status,
64 Self::TlsCertificateInvalid(status) => *status,
65 Self::WebSocketFrameTooLarge(status) => *status,
66 Self::WebSocketOpcodeUnsupported(status) => *status,
67 Self::WebSocketMaskMissing(status) => *status,
68 Self::WebSocketPayloadCorrupted(status) => *status,
69 Self::WebSocketInvalidUtf8(status) => *status,
70 Self::WebSocketInvalidCloseCode(status) => *status,
71 Self::WebSocketInvalidExtension(status) => *status,
72 Self::HttpRequestPartsInsufficient(status) => *status,
73 Self::TcpStreamConnect(status) => *status,
74 Self::TlsConnectorBuild(status) => *status,
75 Self::InvalidUrl(status) => *status,
76 Self::ConfigReadError(status) => *status,
77 Self::TcpStreamConnectString(status) => *status,
78 Self::TlsConnectorBuildString(status) => *status,
79 Self::Request(_) => HttpStatus::BadRequest,
80 Self::Unknown(status) => *status,
81 }
82 }
83
84 /// Gets the numeric HTTP status code associated with this error.
85 ///
86 /// Returns the numeric status code (e.g., 400, 404, 500) that corresponds to this error.
87 ///
88 /// # Arguments
89 ///
90 /// - `&self` - The RequestError instance.
91 ///
92 /// # Returns
93 ///
94 /// - `ResponseStatusCode` - The numeric HTTP status code.
95 pub fn get_http_status_code(&self) -> ResponseStatusCode {
96 self.get_http_status().code()
97 }
98}
99
100impl Default for RequestConfigData {
101 /// Creates a `RequestConfig` with secure default values.
102 ///
103 /// # Returns
104 ///
105 /// - `RequestConfigData ` - A new config instance with secure defaults.
106 #[inline(always)]
107 fn default() -> Self {
108 Self {
109 buffer_size: DEFAULT_BUFFER_SIZE,
110 max_request_line_length: DEFAULT_MAX_REQUEST_LINE_LENGTH,
111 max_path_length: DEFAULT_MAX_PATH_LENGTH,
112 max_query_length: DEFAULT_MAX_QUERY_LENGTH,
113 max_header_line_length: DEFAULT_MAX_HEADER_LINE_LENGTH,
114 max_header_count: DEFAULT_MAX_HEADER_COUNT,
115 max_header_key_length: DEFAULT_MAX_HEADER_KEY_LENGTH,
116 max_header_value_length: DEFAULT_MAX_HEADER_VALUE_LENGTH,
117 max_body_size: DEFAULT_MAX_BODY_SIZE,
118 max_ws_frame_size: DEFAULT_MAX_WS_FRAME_SIZE,
119 max_ws_frames: DEFAULT_MAX_WS_FRAMES,
120 http_read_timeout_ms: DEFAULT_HTTP_READ_TIMEOUT_MS,
121 ws_read_timeout_ms: DEFAULT_WS_READ_TIMEOUT_MS,
122 }
123 }
124}
125
126impl RequestConfigData {
127 /// Creates a config optimized for low-security environments.
128 ///
129 /// This configuration uses less restrictive limits to provide
130 /// basic protection against common attacks.
131 ///
132 /// # Returns
133 ///
134 /// - `RequestConfigData ` - A new config with low-security settings.
135 #[inline(always)]
136 pub(super) fn low_security() -> Self {
137 Self {
138 buffer_size: DEFAULT_LOW_SECURITY_BUFFER_SIZE,
139 max_request_line_length: DEFAULT_LOW_SECURITY_MAX_REQUEST_LINE_LENGTH,
140 max_path_length: DEFAULT_LOW_SECURITY_MAX_PATH_LENGTH,
141 max_query_length: DEFAULT_LOW_SECURITY_MAX_QUERY_LENGTH,
142 max_header_line_length: DEFAULT_LOW_SECURITY_MAX_HEADER_LINE_LENGTH,
143 max_header_count: DEFAULT_LOW_SECURITY_MAX_HEADER_COUNT,
144 max_header_key_length: DEFAULT_LOW_SECURITY_MAX_HEADER_KEY_LENGTH,
145 max_header_value_length: DEFAULT_LOW_SECURITY_MAX_HEADER_VALUE_LENGTH,
146 max_body_size: DEFAULT_LOW_SECURITY_MAX_BODY_SIZE,
147 max_ws_frame_size: DEFAULT_LOW_SECURITY_MAX_WS_FRAME_SIZE,
148 max_ws_frames: DEFAULT_LOW_SECURITY_MAX_WS_FRAMES,
149 http_read_timeout_ms: DEFAULT_LOW_SECURITY_HTTP_READ_TIMEOUT_MS,
150 ws_read_timeout_ms: DEFAULT_LOW_SECURITY_WS_READ_TIMEOUT_MS,
151 }
152 }
153
154 /// Creates a config optimized for high-security environments.
155 ///
156 /// This configuration uses more restrictive limits to provide
157 /// maximum protection against various attacks.
158 ///
159 /// # Returns
160 ///
161 /// - `RequestConfigData ` - A new config with high-security settings.
162 #[inline(always)]
163 pub(super) fn high_security() -> Self {
164 Self {
165 buffer_size: DEFAULT_HIGH_SECURITY_BUFFER_SIZE,
166 max_request_line_length: DEFAULT_HIGH_SECURITY_MAX_REQUEST_LINE_LENGTH,
167 max_path_length: DEFAULT_HIGH_SECURITY_MAX_PATH_LENGTH,
168 max_query_length: DEFAULT_HIGH_SECURITY_MAX_QUERY_LENGTH,
169 max_header_line_length: DEFAULT_HIGH_SECURITY_MAX_HEADER_LINE_LENGTH,
170 max_header_count: DEFAULT_HIGH_SECURITY_MAX_HEADER_COUNT,
171 max_header_key_length: DEFAULT_HIGH_SECURITY_MAX_HEADER_KEY_LENGTH,
172 max_header_value_length: DEFAULT_HIGH_SECURITY_MAX_HEADER_VALUE_LENGTH,
173 max_body_size: DEFAULT_HIGH_SECURITY_MAX_BODY_SIZE,
174 max_ws_frame_size: DEFAULT_HIGH_SECURITY_MAX_WS_FRAME_SIZE,
175 max_ws_frames: DEFAULT_HIGH_SECURITY_MAX_WS_FRAMES,
176 http_read_timeout_ms: DEFAULT_HIGH_SECURITY_HTTP_READ_TIMEOUT_MS,
177 ws_read_timeout_ms: DEFAULT_HIGH_SECURITY_WS_READ_TIMEOUT_MS,
178 }
179 }
180}
181
182/// Implementation of `Default` trait for `RequestConfig`.
183impl Default for RequestConfig {
184 /// Creates a new `RequestConfig` with default secure settings.
185 ///
186 /// This constructor initializes the configuration with standard security limits
187 /// suitable for most HTTP request parsing scenarios.
188 ///
189 /// # Returns
190 ///
191 /// - `Self` - A new `RequestConfig` instance with default settings.
192 #[inline(always)]
193 fn default() -> Self {
194 Self(arc_rwlock(RequestConfigData::default()))
195 }
196}
197
198/// Implementation of `PartialEq` trait for `RequestConfig`.
199impl PartialEq for RequestConfig {
200 /// Compares two `RequestConfig` instances for equality.
201 ///
202 /// # Arguments
203 ///
204 /// - `&self` - The first `RequestConfig` instance.
205 /// - `other` - The second `RequestConfig` instance to compare.
206 ///
207 /// # Returns
208 ///
209 /// - `bool` - `true` if the instances are equal, `false` otherwise.
210 fn eq(&self, other: &Self) -> bool {
211 if Arc::ptr_eq(self.get_0(), other.get_0()) {
212 return true;
213 }
214 if let (Ok(s), Ok(o)) = (self.get_0().try_read(), other.get_0().try_read()) {
215 *s == *o
216 } else {
217 false
218 }
219 }
220}
221
222/// Implementation of `Eq` trait for `RequestConfig`.
223impl Eq for RequestConfig {}
224
225/// Implementation of `From` trait for `RequestConfig`.
226impl From<RequestConfigData> for RequestConfig {
227 /// Converts a `RequestConfigData` into a `RequestConfig`.
228 ///
229 /// # Arguments
230 ///
231 /// - `RequestConfigData` - The wrapped context data.
232 ///
233 /// # Returns
234 ///
235 /// - `RequestConfig` - The newly created context instance.
236 #[inline(always)]
237 fn from(ctx: RequestConfigData) -> Self {
238 Self(arc_rwlock(ctx))
239 }
240}
241
242impl RequestConfig {
243 /// Creates a new `RequestConfig` with default secure settings.
244 ///
245 /// This constructor initializes the configuration with standard security limits
246 /// suitable for most HTTP request parsing scenarios.
247 ///
248 /// # Returns
249 ///
250 /// - `Self` - A new `RequestConfig` instance with default settings.
251 pub async fn new() -> Self {
252 Self(arc_rwlock(RequestConfigData::default()))
253 }
254
255 /// Creates a new `RequestConfig` from a JSON string.
256 ///
257 /// # Arguments
258 ///
259 /// - `AsRef<str>` - The configuration.
260 ///
261 /// # Returns
262 ///
263 /// - `Result<RequestConfig, serde_json::Error>` - The parsed `RequestConfig` or an error.
264 pub fn from_json<C>(json: C) -> Result<RequestConfig, serde_json::Error>
265 where
266 C: AsRef<str>,
267 {
268 serde_json::from_str(json.as_ref()).map(|data: RequestConfigData| Self::from(data))
269 }
270
271 /// Creates a new `RequestConfig` with low-security settings.
272 ///
273 /// This constructor initializes the configuration with less restrictive limits
274 /// to provide maximum protection against various attacks in high-risk environments.
275 ///
276 /// # Returns
277 ///
278 /// - `Self` - A new `RequestConfig` instance with low-security settings.
279 pub async fn low_security() -> Self {
280 Self(arc_rwlock(RequestConfigData::low_security()))
281 }
282
283 /// Creates a new `RequestConfig` with high-security settings.
284 ///
285 /// This constructor initializes the configuration with more restrictive limits
286 /// to provide maximum protection against various attacks in high-risk environments.
287 ///
288 /// # Returns
289 ///
290 /// - `Self` - A new `RequestConfig` instance with high-security settings.
291 pub async fn high_security() -> Self {
292 Self(arc_rwlock(RequestConfigData::high_security()))
293 }
294
295 /// Acquires a read lock on the inner configuration.
296 ///
297 /// This method returns a `RwLockReadGuard` that allows reading the
298 /// `RequestConfigData ` values. Multiple threads can read concurrently.
299 ///
300 /// # Returns
301 ///
302 /// - `RwLockReadGuard<'_, RequestConfigData >` - A read guard providing access to the inner configuration.
303 async fn read(&'_ self) -> RwLockReadGuard<'_, RequestConfigData> {
304 self.get_0().read().await
305 }
306
307 /// Acquires a write lock on the inner configuration.
308 ///
309 /// This method returns a `RwLockWriteGuard` that allows mutating the
310 /// `RequestConfigData ` values. Write access is exclusive.
311 ///
312 /// # Returns
313 ///
314 /// - `RwLockWriteGuard<'_, RequestConfigData >` - A write guard providing exclusive access to the inner configuration.
315 async fn write(&'_ self) -> RwLockWriteGuard<'_, RequestConfigData> {
316 self.get_0().write().await
317 }
318
319 /// Sets the configuration data.
320 ///
321 /// # Arguments
322 ///
323 /// - `RequestConfigData` - The configuration data.
324 ///
325 /// # Returns
326 ///
327 /// - `&Self` - The RequestConfig instance for chaining.
328 pub async fn data(&self, data: RequestConfigData) -> &Self {
329 *self.write().await = data;
330 self
331 }
332
333 /// Gets the configuration data.
334 ///
335 /// # Returns
336 ///
337 /// - `RequestConfigData ` - The inner configuration.
338 pub async fn get_data(&self) -> RequestConfigData {
339 *self.read().await
340 }
341
342 /// Sets the buffer size for reading operations.
343 ///
344 /// # Arguments
345 ///
346 /// - `usize` - The buffer size in bytes.
347 ///
348 /// # Returns
349 ///
350 /// - `&Self` - The RequestConfig instance for chaining.
351 pub async fn buffer_size(&self, buffer_size: usize) -> &Self {
352 self.write().await.set_buffer_size(buffer_size);
353 self
354 }
355
356 /// Sets the maximum length for HTTP request line in bytes.
357 ///
358 /// # Arguments
359 ///
360 /// - `usize` - The maximum request line length.
361 ///
362 /// # Returns
363 ///
364 /// - `&Self` - The RequestConfig instance for chaining.
365 pub async fn max_request_line_length(&self, max_request_line_length: usize) -> &Self {
366 self.write()
367 .await
368 .set_max_request_line_length(max_request_line_length);
369 self
370 }
371
372 /// Sets the maximum length for URL path in bytes.
373 ///
374 /// # Arguments
375 ///
376 /// - `usize` - The maximum path length.
377 ///
378 /// # Returns
379 ///
380 /// - `&Self` - The RequestConfig instance for chaining.
381 pub async fn max_path_length(&self, max_path_length: usize) -> &Self {
382 self.write().await.set_max_path_length(max_path_length);
383 self
384 }
385
386 /// Sets the maximum length for query string in bytes.
387 ///
388 /// # Arguments
389 ///
390 /// - `usize` - The maximum query string length.
391 ///
392 /// # Returns
393 ///
394 /// - `&Self` - The RequestConfig instance for chaining.
395 pub async fn max_query_length(&self, max_query_length: usize) -> &Self {
396 self.write().await.set_max_query_length(max_query_length);
397 self
398 }
399
400 /// Sets the maximum length for a single header line in bytes.
401 ///
402 /// # Arguments
403 ///
404 /// - `usize` - The maximum header line length.
405 ///
406 /// # Returns
407 ///
408 /// - `&Self` - The RequestConfig instance for chaining.
409 pub async fn max_header_line_length(&self, max_header_line_length: usize) -> &Self {
410 self.write()
411 .await
412 .set_max_header_line_length(max_header_line_length);
413 self
414 }
415
416 /// Sets the maximum number of headers allowed in a request.
417 ///
418 /// # Arguments
419 ///
420 /// - `usize` - The maximum header count.
421 ///
422 /// # Returns
423 ///
424 /// - `&Self` - The RequestConfig instance for chaining.
425 pub async fn max_header_count(&self, max_header_count: usize) -> &Self {
426 self.write().await.set_max_header_count(max_header_count);
427 self
428 }
429
430 /// Sets the maximum length for a header key in bytes.
431 ///
432 /// # Arguments
433 ///
434 /// - `usize` - The maximum header key length.
435 ///
436 /// # Returns
437 ///
438 /// - `&Self` - The RequestConfig instance for chaining.
439 pub async fn max_header_key_length(&self, max_header_key_length: usize) -> &Self {
440 self.write()
441 .await
442 .set_max_header_key_length(max_header_key_length);
443 self
444 }
445
446 /// Sets the maximum length for a header value in bytes.
447 ///
448 /// # Arguments
449 ///
450 /// - `usize` - The maximum header value length.
451 ///
452 /// # Returns
453 ///
454 /// - `&Self` - The RequestConfig instance for chaining.
455 pub async fn max_header_value_length(&self, max_header_value_length: usize) -> &Self {
456 self.write()
457 .await
458 .set_max_header_value_length(max_header_value_length);
459 self
460 }
461
462 /// Sets the maximum size for request body in bytes.
463 ///
464 /// # Arguments
465 ///
466 /// - `usize` - The maximum body size.
467 ///
468 /// # Returns
469 ///
470 /// - `&Self` - The RequestConfig instance for chaining.
471 pub async fn max_body_size(&self, max_body_size: usize) -> &Self {
472 self.write().await.set_max_body_size(max_body_size);
473 self
474 }
475
476 /// Sets the maximum size for WebSocket frame in bytes.
477 ///
478 /// # Arguments
479 ///
480 /// - `usize` - The maximum WebSocket frame size.
481 ///
482 /// # Returns
483 ///
484 /// - `&Self` - The RequestConfig instance for chaining.
485 pub async fn max_ws_frame_size(&self, max_ws_frame_size: usize) -> &Self {
486 self.write().await.set_max_ws_frame_size(max_ws_frame_size);
487 self
488 }
489
490 /// Sets the maximum number of WebSocket frames to process in a single request.
491 ///
492 /// # Arguments
493 ///
494 /// - `usize` - The maximum WebSocket frames count.
495 ///
496 /// # Returns
497 ///
498 /// - `&Self` - The RequestConfig instance for chaining.
499 pub async fn max_ws_frames(&self, max_ws_frames: usize) -> &Self {
500 self.write().await.set_max_ws_frames(max_ws_frames);
501 self
502 }
503
504 /// Sets the timeout for reading HTTP request in milliseconds.
505 ///
506 /// # Arguments
507 ///
508 /// - `u64` - The HTTP read timeout in milliseconds.
509 ///
510 /// # Returns
511 ///
512 /// - `&Self` - The RequestConfig instance for chaining.
513 pub async fn http_read_timeout_ms(&self, http_read_timeout_ms: u64) -> &Self {
514 self.write()
515 .await
516 .set_http_read_timeout_ms(http_read_timeout_ms);
517 self
518 }
519
520 /// Sets the timeout for reading WebSocket frames in milliseconds.
521 ///
522 /// # Arguments
523 ///
524 /// - `u64` - The WebSocket read timeout in milliseconds.
525 ///
526 /// # Returns
527 ///
528 /// - `&Self` - The RequestConfig instance for chaining.
529 pub async fn ws_read_timeout_ms(&self, ws_read_timeout_ms: u64) -> &Self {
530 self.write()
531 .await
532 .set_ws_read_timeout_ms(ws_read_timeout_ms);
533 self
534 }
535}
536
537/// Provides a default value for `Request`.
538///
539/// Returns a new `Request` instance with all fields initialized to their default values.
540impl Default for Request {
541 #[inline(always)]
542 fn default() -> Self {
543 Self {
544 method: Method::default(),
545 host: String::new(),
546 version: HttpVersion::default(),
547 path: String::new(),
548 querys: hash_map_xx_hash3_64(),
549 headers: hash_map_xx_hash3_64(),
550 body: Vec::new(),
551 }
552 }
553}
554
555impl Request {
556 /// Parses a query string as_ref key-value pairs.
557 ///
558 /// Expects format "key1=value1&key2=value2". Empty values are allowed.
559 ///
560 /// # Arguments
561 ///
562 /// - `AsRef<str>` - The query string to parse.
563 ///
564 /// # Returns
565 ///
566 /// - `RequestQuerys` - The parsed query parameters.
567 fn parse_querys<Q>(query: Q) -> RequestQuerys
568 where
569 Q: AsRef<str>,
570 {
571 let mut query_map: RequestQuerys = hash_map_xx_hash3_64();
572 for pair in query.as_ref().split(AND) {
573 if let Some((key, value)) = pair.split_once(EQUAL) {
574 if !key.is_empty() {
575 query_map.insert(key.to_string(), value.to_string());
576 }
577 } else if !pair.is_empty() {
578 query_map.insert(pair.to_string(), String::new());
579 }
580 }
581 query_map
582 }
583
584 /// Checks if a header line exceeds the maximum allowed length.
585 ///
586 /// # Arguments
587 ///
588 /// - `usize`: The number of bytes read for the header line.
589 /// - `usize`: The maximum allowed length for a header line.
590 ///
591 /// # Returns
592 ///
593 /// - `Option<RequestError>`: Returns an error if the limit is exceeded and not in low security mode.
594 #[inline(always)]
595 fn check_header_line_length(
596 bytes_read: usize,
597 max_header_line_length: usize,
598 ) -> Option<RequestError> {
599 if bytes_read > max_header_line_length
600 && max_header_line_length != DEFAULT_LOW_SECURITY_MAX_HEADER_LINE_LENGTH
601 {
602 return Some(RequestError::HeaderLineTooLong(
603 HttpStatus::RequestHeaderFieldsTooLarge,
604 ));
605 }
606 None
607 }
608
609 /// Checks if the header count exceeds the maximum allowed.
610 ///
611 /// # Arguments
612 ///
613 /// - `usize`: The current number of headers parsed.
614 /// - `usize`: The maximum allowed number of headers.
615 ///
616 /// # Returns
617 ///
618 /// - `Option<RequestError>`: Returns an error if the limit is exceeded and not in low security mode.
619 #[inline(always)]
620 fn check_header_count(header_count: usize, max_header_count: usize) -> Option<RequestError> {
621 if header_count > max_header_count
622 && max_header_count != DEFAULT_LOW_SECURITY_MAX_HEADER_COUNT
623 {
624 return Some(RequestError::TooManyHeaders(
625 HttpStatus::RequestHeaderFieldsTooLarge,
626 ));
627 }
628 None
629 }
630
631 /// Checks if a header key exceeds the maximum allowed length.
632 ///
633 /// # Arguments
634 ///
635 /// - `&str`: The header key to check.
636 /// - `usize`: The maximum allowed length for a header key.
637 ///
638 /// # Returns
639 ///
640 /// - `Option<RequestError>`: Returns an error if the limit is exceeded and not in low security mode.
641 #[inline(always)]
642 fn check_header_key_length(key: &str, max_header_key_length: usize) -> Option<RequestError> {
643 if key.len() > max_header_key_length
644 && max_header_key_length != DEFAULT_LOW_SECURITY_MAX_HEADER_KEY_LENGTH
645 {
646 return Some(RequestError::HeaderKeyTooLong(
647 HttpStatus::RequestHeaderFieldsTooLarge,
648 ));
649 }
650 None
651 }
652
653 /// Checks if a header value exceeds the maximum allowed length.
654 ///
655 /// # Arguments
656 ///
657 /// - `&str`: The header value to check.
658 /// - `usize`: The maximum allowed length for a header value.
659 ///
660 /// # Returns
661 ///
662 /// - `Option<RequestError>`: Returns an error if the limit is exceeded and not in low security mode.
663 #[inline(always)]
664 fn check_header_value_length(
665 value: &str,
666 max_header_value_length: usize,
667 ) -> Option<RequestError> {
668 if value.len() > max_header_value_length
669 && max_header_value_length != DEFAULT_LOW_SECURITY_MAX_HEADER_VALUE_LENGTH
670 {
671 return Some(RequestError::HeaderValueTooLong(
672 HttpStatus::RequestHeaderFieldsTooLarge,
673 ));
674 }
675 None
676 }
677
678 /// Parses the Content-Length header value and validates it against max body size.
679 ///
680 /// # Arguments
681 ///
682 /// - `&str`: The Content-Length header value string.
683 /// - `usize`: The maximum allowed body size.
684 ///
685 /// # Returns
686 ///
687 /// - `Result<usize, RequestError>`: The parsed content length or an error.
688 #[inline(always)]
689 fn parse_content_length(value: &str, max_body_size: usize) -> Result<usize, RequestError> {
690 let length: usize = value
691 .parse::<usize>()
692 .map_err(|_| RequestError::InvalidContentLength(HttpStatus::BadRequest))?;
693 if length > max_body_size && max_body_size != DEFAULT_LOW_SECURITY_MAX_BODY_SIZE {
694 return Err(RequestError::ContentLengthTooLarge(
695 HttpStatus::PayloadTooLarge,
696 ));
697 }
698 Ok(length)
699 }
700
701 /// Parses HTTP headers from a buffered reader.
702 ///
703 /// This method reads header lines from the provided buffered reader until an empty line
704 /// is encountered, which indicates the end of headers. It validates header count, length,
705 /// and content according to the provided configuration.
706 ///
707 /// # Arguments
708 ///
709 /// - `&mut AsyncBufReadExt + Unpin`: A mutable reference to a buffered reader implementing `AsyncBufReadExt`.
710 /// - `&RequestConfigData`: Configuration for security limits and buffer settings.
711 ///
712 /// # Returns
713 ///
714 /// - `Result<(RequestHeaders, RequestHost, usize), RequestError>`: A tuple containing:
715 /// - The parsed headers as a hash map
716 /// - The host value extracted from the Host header
717 /// - The content length extracted from the Content-Length header
718 /// - Or an error if parsing fails
719 async fn parse_headers<R>(
720 reader: &mut R,
721 config: &RequestConfigData,
722 ) -> Result<(RequestHeaders, RequestHost, usize), RequestError>
723 where
724 R: AsyncBufReadExt + Unpin,
725 {
726 let buffer_size: usize = config.get_buffer_size();
727 let max_header_line_length: usize = config.get_max_header_line_length();
728 let max_header_count: usize = config.get_max_header_count();
729 let max_header_key_length: usize = config.get_max_header_key_length();
730 let max_header_value_length: usize = config.get_max_header_value_length();
731 let max_body_size: usize = config.get_max_body_size();
732 let mut headers: RequestHeaders = hash_map_xx_hash3_64();
733 let mut host: RequestHost = String::new();
734 let mut content_length: usize = 0;
735 let mut header_count: usize = 0;
736 loop {
737 let header_line: &mut String = &mut String::with_capacity(buffer_size);
738 let bytes_read: usize = AsyncBufReadExt::read_line(reader, header_line)
739 .await
740 .map_err(|_| RequestError::HttpRead(HttpStatus::BadRequest))?;
741 if let Some(err) = Self::check_header_line_length(bytes_read, max_header_line_length) {
742 return Err(err);
743 }
744 let header_line: &str = header_line.trim();
745 if header_line.is_empty() {
746 break;
747 }
748 header_count += 1;
749 if let Some(err) = Self::check_header_count(header_count, max_header_count) {
750 return Err(err);
751 }
752 let (key_part, value_part): (&str, &str) = match header_line.split_once(COLON) {
753 Some(parts) => parts,
754 None => continue,
755 };
756 let key: String = key_part.trim().to_ascii_lowercase();
757 if key.is_empty() {
758 continue;
759 }
760 if let Some(err) = Self::check_header_key_length(&key, max_header_key_length) {
761 return Err(err);
762 }
763 let value: String = value_part.trim().to_string();
764 if let Some(err) = Self::check_header_value_length(&value, max_header_value_length) {
765 return Err(err);
766 }
767 match key.as_str() {
768 HOST => host = value.clone(),
769 CONTENT_LENGTH => {
770 content_length = Self::parse_content_length(&value, max_body_size)?;
771 }
772 _ => {}
773 }
774 headers.entry(key).or_default().push_back(value);
775 }
776 Ok((headers, host, content_length))
777 }
778
779 /// Parses the HTTP request content from the stream.
780 ///
781 /// This is an internal helper function that performs the actual parsing.
782 ///
783 /// # Arguments
784 ///
785 /// - `&ArcRwLock<TcpStream>` - The TCP stream to read from.
786 /// - `&RequestConfigData` - Configuration for security limits and buffer settings.
787 ///
788 /// # Returns
789 ///
790 /// - `Result<Request, RequestError>` - The parsed request or an error.
791 async fn parse_http_from_stream(
792 stream: &ArcRwLockStream,
793 config: &RequestConfigData,
794 ) -> Result<Request, RequestError> {
795 let buffer_size: usize = config.get_buffer_size();
796 let max_request_line_length: usize = config.get_max_request_line_length();
797 let max_path_length: usize = config.get_max_path_length();
798 let max_query_length: usize = config.get_max_query_length();
799 let mut buf_stream: RwLockWriteGuard<'_, TcpStream> = stream.write().await;
800 let reader: &mut BufReader<&mut TcpStream> =
801 &mut BufReader::with_capacity(buffer_size, &mut buf_stream);
802 let mut request_line: String = String::with_capacity(buffer_size);
803 let bytes_read: usize = AsyncBufReadExt::read_line(reader, &mut request_line)
804 .await
805 .map_err(|_| RequestError::HttpRead(HttpStatus::BadRequest))?;
806 if bytes_read > max_request_line_length
807 && max_request_line_length != DEFAULT_LOW_SECURITY_MAX_REQUEST_LINE_LENGTH
808 {
809 return Err(RequestError::RequestTooLong(HttpStatus::BadRequest));
810 }
811 let parts: Vec<&str> = request_line.split_whitespace().collect();
812 let parts_len: usize = parts.len();
813 if parts_len < 3 {
814 return Err(RequestError::HttpRequestPartsInsufficient(
815 HttpStatus::BadRequest,
816 ));
817 }
818 let method: RequestMethod = parts[0]
819 .parse::<RequestMethod>()
820 .unwrap_or(Method::Unknown(parts[0].to_string()));
821 let full_path: &str = parts[1];
822 if full_path.len() > max_path_length
823 && max_path_length != DEFAULT_LOW_SECURITY_MAX_PATH_LENGTH
824 {
825 return Err(RequestError::PathTooLong(HttpStatus::URITooLong));
826 }
827 let full_path: RequestPath = full_path.to_string();
828 let version: RequestVersion = parts[2]
829 .parse::<RequestVersion>()
830 .unwrap_or(RequestVersion::Unknown(parts[2].to_string()));
831 let hash_index: Option<usize> = full_path.find(HASH);
832 let query_index: Option<usize> = full_path.find(QUERY);
833 let query_string: String = query_index.map_or_else(String::new, |i| {
834 let temp: &str = &full_path[i + 1..];
835 if hash_index.is_none() || hash_index.unwrap() <= i {
836 return temp.to_owned();
837 }
838 temp.split(HASH).next().unwrap_or_default().to_owned()
839 });
840 if query_string.len() > max_query_length
841 && max_query_length != DEFAULT_LOW_SECURITY_MAX_QUERY_LENGTH
842 {
843 return Err(RequestError::QueryTooLong(HttpStatus::URITooLong));
844 }
845 let querys: RequestQuerys = Self::parse_querys(&query_string);
846 let path: RequestPath = if let Some(i) = query_index.or(hash_index) {
847 full_path[..i].to_owned()
848 } else {
849 full_path.to_owned()
850 };
851 let (headers, host, content_length): (RequestHeaders, RequestHost, usize) =
852 Self::parse_headers(reader, config).await?;
853 let mut body: RequestBody = Vec::with_capacity(content_length);
854 if content_length > 0 {
855 body.resize(content_length, 0);
856 AsyncReadExt::read_exact(reader, &mut body)
857 .await
858 .map_err(|_| RequestError::ReadConnection(HttpStatus::BadRequest))?;
859 }
860 Ok(Request {
861 method,
862 host,
863 version,
864 path,
865 querys,
866 headers,
867 body,
868 })
869 }
870
871 /// Parses an HTTP request from a TCP stream.
872 ///
873 /// Wraps the stream in a buffered reader and delegates to `http_from_reader`.
874 /// If the timeout is u64::MAX, no timeout is applied.
875 ///
876 /// # Arguments
877 ///
878 /// - `&ArcRwLock<TcpStream>` - The TCP stream to read from.
879 /// - `&RequestConfigData` - Configuration for security limits and buffer settings.
880 ///
881 /// # Returns
882 ///
883 /// - `Result<Request, RequestError>` - The parsed request or an error.
884 pub async fn http_from_stream(
885 stream: &ArcRwLockStream,
886 config: &RequestConfigData,
887 ) -> Result<Request, RequestError> {
888 let http_read_timeout_ms: u64 = config.get_http_read_timeout_ms();
889 if http_read_timeout_ms == u64::MAX {
890 return Self::parse_http_from_stream(stream, config).await;
891 }
892 let duration: Duration = Duration::from_millis(http_read_timeout_ms);
893 timeout(duration, Self::parse_http_from_stream(stream, config))
894 .await
895 .map_err(|_| RequestError::ReadTimeout(HttpStatus::RequestTimeout))?
896 }
897
898 /// Converts an I/O error to a `RequestError`.
899 ///
900 /// # Arguments
901 ///
902 /// - `std::io::Error`: The I/O error to convert.
903 ///
904 /// # Returns
905 ///
906 /// - `RequestError`: The corresponding request error.
907 #[inline(always)]
908 fn io_error_to_request_error(error: std::io::Error) -> RequestError {
909 let kind: ErrorKind = error.kind();
910 if kind == ErrorKind::ConnectionReset || kind == ErrorKind::ConnectionAborted {
911 return RequestError::ClientDisconnected(HttpStatus::BadRequest);
912 }
913 RequestError::Unknown(HttpStatus::InternalServerError)
914 }
915
916 /// Checks if the WebSocket frame count exceeds the maximum allowed.
917 ///
918 /// # Arguments
919 ///
920 /// - `usize`: The current number of frames.
921 /// - `usize`: The maximum allowed number of frames.
922 ///
923 /// # Returns
924 ///
925 /// - `Option<RequestError>`: Returns an error if the limit is exceeded and not in low security mode.
926 #[inline(always)]
927 fn check_ws_frame_count(frame_count: usize, max_ws_frames: usize) -> Option<RequestError> {
928 if frame_count > max_ws_frames && max_ws_frames != DEFAULT_LOW_SECURITY_MAX_WS_FRAMES {
929 return Some(RequestError::TooManyHeaders(
930 HttpStatus::RequestHeaderFieldsTooLarge,
931 ));
932 }
933 None
934 }
935
936 /// Reads data from the stream with optional timeout handling.
937 ///
938 /// # Arguments
939 ///
940 /// - `&ArcRwLockStream`: The TCP stream to read from.
941 /// - `&mut [u8]`: The buffer to read data into.
942 /// - `Duration`: The timeout duration.
943 /// - `bool`: Whether to use timeout.
944 /// - `&mut bool`: Mutable reference to track if we got a client response.
945 ///
946 /// # Returns
947 ///
948 /// - `Result<Option<usize>, RequestError>`: The number of bytes read, None for timeout/ping, or an error.
949 async fn read_stream_ws_data(
950 stream: &ArcRwLockStream,
951 temp_buffer: &mut [u8],
952 timeout_duration: Duration,
953 use_timeout: bool,
954 is_client_response: &mut bool,
955 ) -> Result<Option<usize>, RequestError> {
956 if use_timeout {
957 return match timeout(timeout_duration, stream.write().await.read(temp_buffer)).await {
958 Ok(result) => match result {
959 Ok(len) => Ok(Some(len)),
960 Err(error) => Err(Self::io_error_to_request_error(error)),
961 },
962 Err(_) => {
963 if !*is_client_response {
964 return Err(RequestError::ReadTimeout(HttpStatus::RequestTimeout));
965 }
966 *is_client_response = false;
967 stream
968 .try_send_body(&PING_FRAME)
969 .await
970 .map_err(|_| RequestError::WriteTimeout(HttpStatus::InternalServerError))?;
971 Ok(None)
972 }
973 };
974 }
975 match stream.write().await.read(temp_buffer).await {
976 Ok(len) => Ok(Some(len)),
977 Err(error) => Err(Self::io_error_to_request_error(error)),
978 }
979 }
980
981 /// Handles a decoded WebSocket Text or Binary frame and accumulates payload data.
982 ///
983 /// # Arguments
984 ///
985 /// - `&WebSocketFrame`: The decoded WebSocket frame.
986 /// - `&mut Vec<u8>`: The accumulated frame data.
987 /// - `usize`: Maximum allowed frame size.
988 /// - `&Request`: The request to update on completion.
989 ///
990 /// # Returns
991 ///
992 /// - `Result<Option<Request>, RequestError>`: Some(request) if frame is complete, None to continue, or error.
993 #[inline(always)]
994 fn handle_ws_text_binary_frame(
995 frame: &WebSocketFrame,
996 full_frame: &mut Vec<u8>,
997 max_ws_frame_size: usize,
998 request: &Request,
999 ) -> Result<Option<Request>, RequestError> {
1000 let payload_data: &[u8] = frame.get_payload_data();
1001 if payload_data.len() > max_ws_frame_size {
1002 return Err(RequestError::WebSocketFrameTooLarge(
1003 HttpStatus::PayloadTooLarge,
1004 ));
1005 }
1006 let len: usize = full_frame.len() + payload_data.len();
1007 if len > max_ws_frame_size && max_ws_frame_size != DEFAULT_LOW_SECURITY_MAX_WS_FRAME_SIZE {
1008 return Err(RequestError::WebSocketFrameTooLarge(
1009 HttpStatus::PayloadTooLarge,
1010 ));
1011 }
1012 full_frame.extend_from_slice(payload_data);
1013 if *frame.get_fin() {
1014 let mut result: Request = request.clone();
1015 result.body = full_frame.clone();
1016 return Ok(Some(result));
1017 }
1018 Ok(None)
1019 }
1020
1021 /// Parses a WebSocket request from a TCP stream.
1022 ///
1023 /// Wraps the stream in a buffered reader and delegates to `ws_from_reader`.
1024 /// If the timeout is u64::MAX, no timeout is applied.
1025 ///
1026 /// # Arguments
1027 ///
1028 /// - `&ArcRwLock<TcpStream>`: The TCP stream to read from.
1029 /// - `&RequestConfigData`: Configuration for security limits and buffer settings.
1030 ///
1031 /// # Returns
1032 ///
1033 /// - `Result<Request, RequestError>`: The parsed WebSocket request or an error.
1034 pub async fn ws_from_stream(
1035 &self,
1036 stream: &ArcRwLockStream,
1037 config: &RequestConfigData,
1038 ) -> Result<Request, RequestError> {
1039 let buffer_size: usize = config.get_buffer_size();
1040 let max_ws_frame_size: usize = config.get_max_ws_frame_size();
1041 let ws_read_timeout_ms: u64 = config.get_ws_read_timeout_ms();
1042 let max_ws_frames: usize = config.get_max_ws_frames();
1043 let mut dynamic_buffer: Vec<u8> = Vec::with_capacity(buffer_size);
1044 let mut temp_buffer: Vec<u8> = vec![0; buffer_size];
1045 let mut full_frame: Vec<u8> = Vec::with_capacity(max_ws_frame_size);
1046 let mut frame_count: usize = 0;
1047 let mut is_client_response: bool = false;
1048 let adjusted_timeout_ms: u64 = (ws_read_timeout_ms >> 1) + (ws_read_timeout_ms & 1);
1049 let timeout_duration: Duration = Duration::from_millis(adjusted_timeout_ms);
1050 let use_timeout: bool = ws_read_timeout_ms != u64::MAX;
1051 loop {
1052 let len: usize = match Self::read_stream_ws_data(
1053 stream,
1054 &mut temp_buffer,
1055 timeout_duration,
1056 use_timeout,
1057 &mut is_client_response,
1058 )
1059 .await
1060 {
1061 Ok(Some(len)) => len,
1062 Ok(None) => continue,
1063 Err(error) => return Err(error),
1064 };
1065 if len == 0 {
1066 return Err(RequestError::IncompleteWebSocketFrame(
1067 HttpStatus::BadRequest,
1068 ));
1069 }
1070 dynamic_buffer.extend_from_slice(&temp_buffer[..len]);
1071 while let Some((frame, consumed)) = WebSocketFrame::decode_ws_frame(&dynamic_buffer) {
1072 is_client_response = true;
1073 dynamic_buffer.drain(0..consumed);
1074 frame_count += 1;
1075 if let Some(err) = Self::check_ws_frame_count(frame_count, max_ws_frames) {
1076 return Err(err);
1077 }
1078 match frame.get_opcode() {
1079 WebSocketOpcode::Close => {
1080 return Err(RequestError::ClientClosedConnection(HttpStatus::BadRequest));
1081 }
1082 WebSocketOpcode::Ping | WebSocketOpcode::Pong => continue,
1083 WebSocketOpcode::Text | WebSocketOpcode::Binary => {
1084 match Self::handle_ws_text_binary_frame(
1085 &frame,
1086 &mut full_frame,
1087 max_ws_frame_size,
1088 self,
1089 ) {
1090 Ok(Some(result)) => return Ok(result),
1091 Ok(None) => continue,
1092 Err(error) => return Err(error),
1093 }
1094 }
1095 _ => {
1096 return Err(RequestError::WebSocketOpcodeUnsupported(
1097 HttpStatus::NotImplemented,
1098 ));
1099 }
1100 }
1101 }
1102 }
1103 }
1104
1105 /// Tries to get a query parameter value by key.
1106 ///
1107 /// The key type must implement AsRef<str> conversion.
1108 ///
1109 /// # Arguments
1110 ///
1111 /// - `AsRef<str>` - The query parameter key (implements AsRef<str>).
1112 ///
1113 /// # Returns
1114 ///
1115 /// - `Option<RequestQuerysValue>` - The parameter value if exists.
1116 #[inline(always)]
1117 pub fn try_get_query<K>(&self, key: K) -> Option<RequestQuerysValue>
1118 where
1119 K: AsRef<str>,
1120 {
1121 self.querys.get(key.as_ref()).cloned()
1122 }
1123
1124 /// Gets a query parameter value by key.
1125 ///
1126 /// The key type must implement AsRef<str> conversion.
1127 ///
1128 /// # Arguments
1129 ///
1130 /// - `AsRef<str>` - The query parameter key (implements AsRef<str>).
1131 ///
1132 /// # Returns
1133 ///
1134 /// - `RequestQuerysValue` - The parameter value if exists.
1135 ///
1136 /// # Panics
1137 ///
1138 /// This function will panic if the query parameter key is not found.
1139 #[inline(always)]
1140 pub fn get_query<K>(&self, key: K) -> RequestQuerysValue
1141 where
1142 K: AsRef<str>,
1143 {
1144 self.try_get_query(key).unwrap()
1145 }
1146
1147 /// Tries to retrieve the value of a request header by its key.
1148 ///
1149 /// # Arguments
1150 ///
1151 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
1152 ///
1153 /// # Returns
1154 ///
1155 /// - `Option<RequestHeadersValue>` - The optional header values.
1156 #[inline(always)]
1157 pub fn try_get_header<K>(&self, key: K) -> Option<RequestHeadersValue>
1158 where
1159 K: AsRef<str>,
1160 {
1161 self.headers.get(key.as_ref()).cloned()
1162 }
1163
1164 /// Retrieves the value of a request header by its key.
1165 ///
1166 /// # Arguments
1167 ///
1168 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
1169 ///
1170 /// # Returns
1171 ///
1172 /// - `RequestHeadersValue` - The optional header values.
1173 ///
1174 /// # Panics
1175 ///
1176 /// This function will panic if the header key is not found.
1177 #[inline(always)]
1178 pub fn get_header<K>(&self, key: K) -> RequestHeadersValue
1179 where
1180 K: AsRef<str>,
1181 {
1182 self.try_get_header(key).unwrap()
1183 }
1184
1185 /// Tries to retrieve the first value of a request header by its key.
1186 ///
1187 /// # Arguments
1188 ///
1189 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
1190 ///
1191 /// # Returns
1192 ///
1193 /// - `Option<RequestHeadersValueItem>` - The first header value if exists.
1194 #[inline(always)]
1195 pub fn try_get_header_front<K>(&self, key: K) -> Option<RequestHeadersValueItem>
1196 where
1197 K: AsRef<str>,
1198 {
1199 self.headers
1200 .get(key.as_ref())
1201 .and_then(|values| values.front().cloned())
1202 }
1203
1204 /// Retrieves the first value of a request header by its key.
1205 ///
1206 /// # Arguments
1207 ///
1208 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
1209 ///
1210 /// # Returns
1211 ///
1212 /// - `RequestHeadersValueItem` - The first header value if exists.
1213 ///
1214 /// # Panics
1215 ///
1216 /// This function will panic if the header key is not found.
1217 #[inline(always)]
1218 pub fn get_header_front<K>(&self, key: K) -> RequestHeadersValueItem
1219 where
1220 K: AsRef<str>,
1221 {
1222 self.try_get_header_front(key).unwrap()
1223 }
1224
1225 /// Tries to retrieve the last value of a request header by its key.
1226 ///
1227 /// # Arguments
1228 ///
1229 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
1230 ///
1231 /// # Returns
1232 ///
1233 /// - `Option<RequestHeadersValueItem>` - The last header value if exists.
1234 #[inline(always)]
1235 pub fn try_get_header_back<K>(&self, key: K) -> Option<RequestHeadersValueItem>
1236 where
1237 K: AsRef<str>,
1238 {
1239 self.headers
1240 .get(key.as_ref())
1241 .and_then(|values| values.back().cloned())
1242 }
1243
1244 /// Retrieves the last value of a request header by its key.
1245 ///
1246 /// # Arguments
1247 ///
1248 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
1249 ///
1250 /// # Returns
1251 ///
1252 /// - `RequestHeadersValueItem` - The last header value if exists.
1253 ///
1254 /// # Panics
1255 ///
1256 /// This function will panic if the header key is not found.
1257 #[inline(always)]
1258 pub fn get_header_back<K>(&self, key: K) -> RequestHeadersValueItem
1259 where
1260 K: AsRef<str>,
1261 {
1262 self.try_get_header_back(key).unwrap()
1263 }
1264
1265 /// Tries to retrieve the number of values for a specific header.
1266 ///
1267 /// # Arguments
1268 ///
1269 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
1270 ///
1271 /// # Returns
1272 ///
1273 /// - `Option<usize>` - The count of values for the header if exists.
1274 #[inline(always)]
1275 pub fn try_get_header_length<K>(&self, key: K) -> Option<usize>
1276 where
1277 K: AsRef<str>,
1278 {
1279 self.headers.get(key.as_ref()).map(|values| values.len())
1280 }
1281
1282 /// Retrieves the number of values for a specific header.
1283 ///
1284 /// # Arguments
1285 ///
1286 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
1287 ///
1288 /// # Returns
1289 ///
1290 /// - `usize` - The count of values for the header.
1291 ///
1292 /// # Panics
1293 ///
1294 /// This function will panic if the header key is not found.
1295 #[inline(always)]
1296 pub fn get_header_length<K>(&self, key: K) -> usize
1297 where
1298 K: AsRef<str>,
1299 {
1300 self.try_get_header_length(key).unwrap()
1301 }
1302
1303 /// Retrieves the total number of header values across all headers.
1304 ///
1305 /// # Returns
1306 ///
1307 /// - `usize` - The total count of all header values.
1308 #[inline(always)]
1309 pub fn get_headers_values_length(&self) -> usize {
1310 self.headers.values().map(|values| values.len()).sum()
1311 }
1312
1313 /// Retrieves the number of unique headers.
1314 ///
1315 /// # Returns
1316 ///
1317 /// - `usize` - The count of unique header keys.
1318 #[inline(always)]
1319 pub fn get_headers_length(&self) -> usize {
1320 self.headers.len()
1321 }
1322
1323 /// Checks if a specific header exists.
1324 ///
1325 /// # Arguments
1326 ///
1327 /// - `AsRef<str>` - The header key to check (must implement AsRef<str>).
1328 ///
1329 /// # Returns
1330 ///
1331 /// - `bool` - Whether the header exists.
1332 #[inline(always)]
1333 pub fn has_header<K>(&self, key: K) -> bool
1334 where
1335 K: AsRef<str>,
1336 {
1337 self.headers.contains_key(key.as_ref())
1338 }
1339
1340 /// Checks if a header contains a specific value.
1341 ///
1342 /// # Arguments
1343 ///
1344 /// - `AsRef<str>` - The header key to check (must implement AsRef<str>).
1345 /// - `AsRef<str>` - The value to search for (must implement AsRef<str>).
1346 ///
1347 /// # Returns
1348 ///
1349 /// - `bool` - Whether the header contains the value.
1350 #[inline(always)]
1351 pub fn has_header_value<K, V>(&self, key: K, value: V) -> bool
1352 where
1353 K: AsRef<str>,
1354 V: AsRef<str>,
1355 {
1356 if let Some(values) = self.headers.get(key.as_ref()) {
1357 values.contains(&value.as_ref().to_owned())
1358 } else {
1359 false
1360 }
1361 }
1362
1363 /// Retrieves the body content of the request as a UTF-8 encoded string.
1364 ///
1365 /// This method uses `String::from_utf8_lossy` to convert the byte slice returned by `self.get_body()` as_ref a string.
1366 /// If the byte slice contains invalid UTF-8 sequences, they will be replaced with the Unicode replacement character ().
1367 ///
1368 /// # Returns
1369 ///
1370 /// - `String` - The body content as a string.
1371 #[inline(always)]
1372 pub fn get_body_string(&self) -> String {
1373 String::from_utf8_lossy(self.get_body()).into_owned()
1374 }
1375
1376 /// Deserializes the body content of the request as_ref a specified type `T`.
1377 ///
1378 /// This method first retrieves the body content as a byte slice using `self.get_body()`.
1379 /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
1380 ///
1381 /// # Arguments
1382 ///
1383 /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
1384 ///
1385 /// # Returns
1386 ///
1387 /// - `Result<T, serde_json::Error>` - The deserialization result.
1388 pub fn try_get_body_json<T>(&self) -> Result<T, serde_json::Error>
1389 where
1390 T: DeserializeOwned,
1391 {
1392 serde_json::from_slice(self.get_body())
1393 }
1394
1395 /// Deserializes the body content of the request as_ref a specified type `T`.
1396 ///
1397 /// This method first retrieves the body content as a byte slice using `self.get_body()`.
1398 /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
1399 ///
1400 /// # Arguments
1401 ///
1402 /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
1403 ///
1404 /// # Returns
1405 ///
1406 /// - `T` - The deserialized body content.
1407 ///
1408 /// # Panics
1409 ///
1410 /// This function will panic if the deserialization fails.
1411 pub fn get_body_json<T>(&self) -> T
1412 where
1413 T: DeserializeOwned,
1414 {
1415 self.try_get_body_json().unwrap()
1416 }
1417
1418 /// Converts the request to a formatted string representation.
1419 ///
1420 /// This method provides a human-readable summary of the request, including its method,
1421 /// host, version, path, query parameters, headers, and body information.
1422 ///
1423 /// # Returns
1424 ///
1425 /// - `String` - The formatted request details.
1426 #[inline(always)]
1427 pub fn get_string(&self) -> String {
1428 let body: &Vec<u8> = self.get_body();
1429 let body_type: &'static str = if std::str::from_utf8(body).is_ok() {
1430 PLAIN
1431 } else {
1432 BINARY
1433 };
1434 format!(
1435 "[Request] => [method]: {}; [host]: {}; [version]: {}; [path]: {}; [querys]: {:?}; [headers]: {:?}; [body]: {} bytes {};",
1436 self.get_method(),
1437 self.get_host(),
1438 self.get_version(),
1439 self.get_path(),
1440 self.get_querys(),
1441 self.get_headers(),
1442 body.len(),
1443 body_type
1444 )
1445 }
1446
1447 /// Retrieves the upgrade type from the request headers.
1448 ///
1449 /// This method looks for the `UPGRADE` header and attempts to parse its value
1450 /// as_ref an `UpgradeType`. If the header is missing or the value is invalid,
1451 /// it returns the default `UpgradeType`.
1452 ///
1453 /// # Returns
1454 ///
1455 /// - `UpgradeType` - The parsed upgrade type.
1456 #[inline(always)]
1457 pub fn get_upgrade_type(&self) -> UpgradeType {
1458 let upgrade_type: UpgradeType = self
1459 .try_get_header_back(UPGRADE)
1460 .and_then(|data| data.parse::<UpgradeType>().ok())
1461 .unwrap_or_default();
1462 upgrade_type
1463 }
1464
1465 /// Checks whether the WebSocket upgrade is enabled for this request.
1466 ///
1467 /// This method determines if the `UPGRADE` header indicates a WebSocket connection.
1468 ///
1469 /// # Returns
1470 ///
1471 /// - `bool` - Whether WebSocket upgrade is enabled.
1472 #[inline(always)]
1473 pub fn is_ws(&self) -> bool {
1474 self.get_upgrade_type().is_ws()
1475 }
1476
1477 /// Checks if the current upgrade type is HTTP/2 cleartext (h2c).
1478 ///
1479 /// # Returns
1480 ///
1481 /// - `bool` - Whether the upgrade type is h2c.
1482 #[inline(always)]
1483 pub fn is_h2c(&self) -> bool {
1484 self.get_upgrade_type().is_h2c()
1485 }
1486
1487 /// Checks if the current upgrade type is TLS (any version).
1488 ///
1489 /// # Returns
1490 ///
1491 /// - `bool` - Whether the upgrade type is TLS.
1492 #[inline(always)]
1493 pub fn is_tls(&self) -> bool {
1494 self.get_upgrade_type().is_tls()
1495 }
1496
1497 /// Checks whether the upgrade type is unknown.
1498 ///
1499 /// # Returns
1500 ///
1501 /// - `bool` - Whether the upgrade type is unknown.
1502 #[inline(always)]
1503 pub fn is_unknown_upgrade(&self) -> bool {
1504 self.get_upgrade_type().is_unknown()
1505 }
1506
1507 /// Checks if the HTTP version is HTTP/1.1 or higher.
1508 ///
1509 /// # Returns
1510 ///
1511 /// - `bool` - Whether the version is HTTP/1.1 or higher.
1512 #[inline(always)]
1513 pub fn is_http1_1_or_higher(&self) -> bool {
1514 self.get_version().is_http1_1_or_higher()
1515 }
1516
1517 /// Checks whether the HTTP version is HTTP/0.9.
1518 ///
1519 /// # Returns
1520 ///
1521 /// - `bool` - Whether the version is HTTP/0.9.
1522 #[inline(always)]
1523 pub fn is_http0_9(&self) -> bool {
1524 self.get_version().is_http0_9()
1525 }
1526
1527 /// Checks whether the HTTP version is HTTP/1.0.
1528 ///
1529 /// # Returns
1530 ///
1531 /// - `bool` - Whether the version is HTTP/1.0.
1532 #[inline(always)]
1533 pub fn is_http1_0(&self) -> bool {
1534 self.get_version().is_http1_0()
1535 }
1536
1537 /// Checks whether the HTTP version is HTTP/1.1.
1538 ///
1539 /// # Returns
1540 ///
1541 /// - `bool` - Whether the version is HTTP/1.1.
1542 #[inline(always)]
1543 pub fn is_http1_1(&self) -> bool {
1544 self.get_version().is_http1_1()
1545 }
1546
1547 /// Checks whether the HTTP version is HTTP/2.
1548 ///
1549 /// # Returns
1550 ///
1551 /// - `bool` - Whether the version is HTTP/2.
1552 #[inline(always)]
1553 pub fn is_http2(&self) -> bool {
1554 self.get_version().is_http2()
1555 }
1556
1557 /// Checks whether the HTTP version is HTTP/3.
1558 ///
1559 /// # Returns
1560 ///
1561 /// - `bool` - Whether the version is HTTP/3.
1562 #[inline(always)]
1563 pub fn is_http3(&self) -> bool {
1564 self.get_version().is_http3()
1565 }
1566
1567 /// Checks whether the HTTP version is unknown.
1568 ///
1569 /// # Returns
1570 ///
1571 /// - `bool` - Whether the version is unknown.
1572 #[inline(always)]
1573 pub fn is_unknown_version(&self) -> bool {
1574 self.get_version().is_unknown()
1575 }
1576
1577 /// Checks whether the version belongs to the HTTP family.
1578 ///
1579 /// # Returns
1580 ///
1581 /// - `bool` - Whether the version is HTTP.
1582 #[inline(always)]
1583 pub fn is_http(&self) -> bool {
1584 self.get_version().is_http()
1585 }
1586
1587 /// Checks whether the request method is GET.
1588 ///
1589 /// # Returns
1590 ///
1591 /// - `bool` - Whether the method is GET.
1592 #[inline(always)]
1593 pub fn is_get(&self) -> bool {
1594 self.get_method().is_get()
1595 }
1596
1597 /// Checks whether the request method is POST.
1598 ///
1599 /// # Returns
1600 ///
1601 /// - `bool` - Whether the method is POST.
1602 #[inline(always)]
1603 pub fn is_post(&self) -> bool {
1604 self.get_method().is_post()
1605 }
1606
1607 /// Checks whether the request method is PUT.
1608 ///
1609 /// # Returns
1610 ///
1611 /// - `bool` - Whether the method is PUT.
1612 #[inline(always)]
1613 pub fn is_put(&self) -> bool {
1614 self.get_method().is_put()
1615 }
1616
1617 /// Checks whether the request method is DELETE.
1618 ///
1619 /// # Returns
1620 ///
1621 /// - `bool` - Whether the method is DELETE.
1622 #[inline(always)]
1623 pub fn is_delete(&self) -> bool {
1624 self.get_method().is_delete()
1625 }
1626
1627 /// Checks whether the request method is PATCH.
1628 ///
1629 /// # Returns
1630 ///
1631 /// - `bool` - Whether the method is PATCH.
1632 #[inline(always)]
1633 pub fn is_patch(&self) -> bool {
1634 self.get_method().is_patch()
1635 }
1636
1637 /// Checks whether the request method is HEAD.
1638 ///
1639 /// # Returns
1640 ///
1641 /// - `bool` - Whether the method is HEAD.
1642 #[inline(always)]
1643 pub fn is_head(&self) -> bool {
1644 self.get_method().is_head()
1645 }
1646
1647 /// Checks whether the request method is OPTIONS.
1648 ///
1649 /// # Returns
1650 ///
1651 /// - `bool` - Whether the method is OPTIONS.
1652 #[inline(always)]
1653 pub fn is_options(&self) -> bool {
1654 self.get_method().is_options()
1655 }
1656
1657 /// Checks whether the request method is CONNECT.
1658 ///
1659 /// # Returns
1660 ///
1661 /// - `bool` - Whether the method is CONNECT.
1662 #[inline(always)]
1663 pub fn is_connect(&self) -> bool {
1664 self.get_method().is_connect()
1665 }
1666
1667 /// Checks whether the request method is TRACE.
1668 ///
1669 /// # Returns
1670 ///
1671 /// - `bool` - Whether the method is TRACE.
1672 #[inline(always)]
1673 pub fn is_trace(&self) -> bool {
1674 self.get_method().is_trace()
1675 }
1676
1677 /// Checks whether the request method is UNKNOWN.
1678 ///
1679 /// # Returns
1680 ///
1681 /// - `bool` - Whether the method is UNKNOWN.
1682 #[inline(always)]
1683 pub fn is_unknown_method(&self) -> bool {
1684 self.get_method().is_unknown()
1685 }
1686
1687 /// Determines if a keep-alive connection should be enabled for this request.
1688 ///
1689 /// This function checks the `Connection` header and the HTTP version to determine
1690 /// if keep-alive should be enabled. The logic is as follows:
1691 ///
1692 /// 1. If the `Connection` header exists:
1693 /// - Returns `true` if the header value is "keep-alive" (case-insensitive).
1694 /// - Returns `false` if the header value is "close" (case-insensitive).
1695 /// 2. If no `Connection` header is present:
1696 /// - Returns `true` if the HTTP version is 1.1 or higher.
1697 /// - Returns `false` otherwise.
1698 ///
1699 /// # Returns
1700 ///
1701 /// - `bool` - Whether keep-alive should be enabled.
1702 #[inline(always)]
1703 pub fn is_enable_keep_alive(&self) -> bool {
1704 if let Some(connection_value) = self.try_get_header_back(CONNECTION) {
1705 if connection_value.eq_ignore_ascii_case(KEEP_ALIVE) {
1706 return true;
1707 } else if connection_value.eq_ignore_ascii_case(CLOSE) {
1708 return self.is_ws();
1709 }
1710 }
1711 self.is_http1_1_or_higher() || self.is_ws()
1712 }
1713
1714 /// Determines if keep-alive should be disabled for this request.
1715 ///
1716 /// # Returns
1717 ///
1718 /// - `bool` - Whether keep-alive should be disabled.
1719 #[inline(always)]
1720 pub fn is_disable_keep_alive(&self) -> bool {
1721 !self.is_enable_keep_alive()
1722 }
1723}