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 high-security environments.
128 ///
129 /// This configuration uses more restrictive limits to provide
130 /// maximum protection against various attacks.
131 ///
132 /// # Returns
133 ///
134 /// - `RequestConfigData ` - A new config with high-security settings.
135 #[inline(always)]
136 pub(super) fn high_security() -> Self {
137 Self {
138 buffer_size: DEFAULT_HIGH_SECURITY_BUFFER_SIZE,
139 max_request_line_length: DEFAULT_HIGH_SECURITY_MAX_REQUEST_LINE_LENGTH,
140 max_path_length: DEFAULT_HIGH_SECURITY_MAX_PATH_LENGTH,
141 max_query_length: DEFAULT_HIGH_SECURITY_MAX_QUERY_LENGTH,
142 max_header_line_length: DEFAULT_HIGH_SECURITY_MAX_HEADER_LINE_LENGTH,
143 max_header_count: DEFAULT_HIGH_SECURITY_MAX_HEADER_COUNT,
144 max_header_key_length: DEFAULT_HIGH_SECURITY_MAX_HEADER_KEY_LENGTH,
145 max_header_value_length: DEFAULT_HIGH_SECURITY_MAX_HEADER_VALUE_LENGTH,
146 max_body_size: DEFAULT_HIGH_SECURITY_MAX_BODY_SIZE,
147 max_ws_frame_size: DEFAULT_HIGH_SECURITY_MAX_WS_FRAME_SIZE,
148 max_ws_frames: DEFAULT_HIGH_SECURITY_MAX_WS_FRAMES,
149 http_read_timeout_ms: DEFAULT_HIGH_SECURITY_HTTP_READ_TIMEOUT_MS,
150 ws_read_timeout_ms: DEFAULT_HIGH_SECURITY_WS_READ_TIMEOUT_MS,
151 }
152 }
153}
154
155/// Implementation of `Default` trait for `RequestConfig`.
156impl Default for RequestConfig {
157 /// Creates a new `RequestConfig` with default secure settings.
158 ///
159 /// This constructor initializes the configuration with standard security limits
160 /// suitable for most HTTP request parsing scenarios.
161 ///
162 /// # Returns
163 ///
164 /// - `Self` - A new `RequestConfig` instance with default settings.
165 #[inline(always)]
166 fn default() -> Self {
167 Self(arc_rwlock(RequestConfigData::default()))
168 }
169}
170
171/// Implementation of `PartialEq` trait for `RequestConfig`.
172impl PartialEq for RequestConfig {
173 /// Compares two `RequestConfig` instances for equality.
174 ///
175 /// # Arguments
176 ///
177 /// - `&self` - The first `RequestConfig` instance.
178 /// - `other` - The second `RequestConfig` instance to compare.
179 ///
180 /// # Returns
181 ///
182 /// - `bool` - `true` if the instances are equal, `false` otherwise.
183 fn eq(&self, other: &Self) -> bool {
184 if Arc::ptr_eq(self.get_0(), other.get_0()) {
185 return true;
186 }
187 if let (Ok(s), Ok(o)) = (self.get_0().try_read(), other.get_0().try_read()) {
188 *s == *o
189 } else {
190 false
191 }
192 }
193}
194
195/// Implementation of `Eq` trait for `RequestConfig`.
196impl Eq for RequestConfig {}
197
198/// Implementation of `From` trait for `RequestConfig`.
199impl From<RequestConfigData> for RequestConfig {
200 /// Converts a `RequestConfigData` into a `RequestConfig`.
201 ///
202 /// # Arguments
203 ///
204 /// - `RequestConfigData` - The wrapped context data.
205 ///
206 /// # Returns
207 ///
208 /// - `RequestConfig` - The newly created context instance.
209 #[inline(always)]
210 fn from(ctx: RequestConfigData) -> Self {
211 Self(arc_rwlock(ctx))
212 }
213}
214
215impl RequestConfig {
216 /// Creates a new `RequestConfig` with default secure settings.
217 ///
218 /// This constructor initializes the configuration with standard security limits
219 /// suitable for most HTTP request parsing scenarios.
220 ///
221 /// # Returns
222 ///
223 /// - `Self` - A new `RequestConfig` instance with default settings.
224 pub async fn new() -> Self {
225 Self(arc_rwlock(RequestConfigData::default()))
226 }
227
228 /// Creates a new `RequestConfig` from a JSON string.
229 ///
230 /// # Arguments
231 ///
232 /// - `AsRef<str>` - The configuration.
233 ///
234 /// # Returns
235 ///
236 /// - `Result<RequestConfig, serde_json::Error>` - The parsed `RequestConfig` or an error.
237 pub fn from_json<C>(json: C) -> Result<RequestConfig, serde_json::Error>
238 where
239 C: AsRef<str>,
240 {
241 serde_json::from_str(json.as_ref()).map(|data: RequestConfigData| Self::from(data))
242 }
243
244 /// Creates a new `RequestConfig` with high-security settings.
245 ///
246 /// This constructor initializes the configuration with more restrictive limits
247 /// to provide maximum protection against various attacks in high-risk environments.
248 ///
249 /// # Returns
250 ///
251 /// - `Self` - A new `RequestConfig` instance with high-security settings.
252 pub async fn high_security() -> Self {
253 Self(arc_rwlock(RequestConfigData::high_security()))
254 }
255
256 /// Acquires a read lock on the inner configuration.
257 ///
258 /// This method returns a `RwLockReadGuard` that allows reading the
259 /// `RequestConfigData ` values. Multiple threads can read concurrently.
260 ///
261 /// # Returns
262 ///
263 /// - `RwLockReadGuard<'_, RequestConfigData >` - A read guard providing access to the inner configuration.
264 async fn read(&'_ self) -> RwLockReadGuard<'_, RequestConfigData> {
265 self.get_0().read().await
266 }
267
268 /// Acquires a write lock on the inner configuration.
269 ///
270 /// This method returns a `RwLockWriteGuard` that allows mutating the
271 /// `RequestConfigData ` values. Write access is exclusive.
272 ///
273 /// # Returns
274 ///
275 /// - `RwLockWriteGuard<'_, RequestConfigData >` - A write guard providing exclusive access to the inner configuration.
276 async fn write(&'_ self) -> RwLockWriteGuard<'_, RequestConfigData> {
277 self.get_0().write().await
278 }
279
280 /// Sets the configuration data.
281 ///
282 /// # Arguments
283 ///
284 /// - `RequestConfigData` - The configuration data.
285 ///
286 /// # Returns
287 ///
288 /// - `&Self` - The RequestConfig instance for chaining.
289 pub async fn data(&self, data: RequestConfigData) -> &Self {
290 *self.write().await = data;
291 self
292 }
293
294 /// Gets the configuration data.
295 ///
296 /// # Returns
297 ///
298 /// - `RequestConfigData ` - The inner configuration.
299 pub async fn get_data(&self) -> RequestConfigData {
300 *self.read().await
301 }
302
303 /// Sets the buffer size for reading operations.
304 ///
305 /// # Arguments
306 ///
307 /// - `usize` - The buffer size in bytes.
308 ///
309 /// # Returns
310 ///
311 /// - `&Self` - The RequestConfig instance for chaining.
312 pub async fn buffer_size(&self, buffer_size: usize) -> &Self {
313 self.write().await.set_buffer_size(buffer_size);
314 self
315 }
316
317 /// Sets the maximum length for HTTP request line in bytes.
318 ///
319 /// # Arguments
320 ///
321 /// - `usize` - The maximum request line length.
322 ///
323 /// # Returns
324 ///
325 /// - `&Self` - The RequestConfig instance for chaining.
326 pub async fn max_request_line_length(&self, max_request_line_length: usize) -> &Self {
327 self.write()
328 .await
329 .set_max_request_line_length(max_request_line_length);
330 self
331 }
332
333 /// Sets the maximum length for URL path in bytes.
334 ///
335 /// # Arguments
336 ///
337 /// - `usize` - The maximum path length.
338 ///
339 /// # Returns
340 ///
341 /// - `&Self` - The RequestConfig instance for chaining.
342 pub async fn max_path_length(&self, max_path_length: usize) -> &Self {
343 self.write().await.set_max_path_length(max_path_length);
344 self
345 }
346
347 /// Sets the maximum length for query string in bytes.
348 ///
349 /// # Arguments
350 ///
351 /// - `usize` - The maximum query string length.
352 ///
353 /// # Returns
354 ///
355 /// - `&Self` - The RequestConfig instance for chaining.
356 pub async fn max_query_length(&self, max_query_length: usize) -> &Self {
357 self.write().await.set_max_query_length(max_query_length);
358 self
359 }
360
361 /// Sets the maximum length for a single header line in bytes.
362 ///
363 /// # Arguments
364 ///
365 /// - `usize` - The maximum header line length.
366 ///
367 /// # Returns
368 ///
369 /// - `&Self` - The RequestConfig instance for chaining.
370 pub async fn max_header_line_length(&self, max_header_line_length: usize) -> &Self {
371 self.write()
372 .await
373 .set_max_header_line_length(max_header_line_length);
374 self
375 }
376
377 /// Sets the maximum number of headers allowed in a request.
378 ///
379 /// # Arguments
380 ///
381 /// - `usize` - The maximum header count.
382 ///
383 /// # Returns
384 ///
385 /// - `&Self` - The RequestConfig instance for chaining.
386 pub async fn max_header_count(&self, max_header_count: usize) -> &Self {
387 self.write().await.set_max_header_count(max_header_count);
388 self
389 }
390
391 /// Sets the maximum length for a header key in bytes.
392 ///
393 /// # Arguments
394 ///
395 /// - `usize` - The maximum header key length.
396 ///
397 /// # Returns
398 ///
399 /// - `&Self` - The RequestConfig instance for chaining.
400 pub async fn max_header_key_length(&self, max_header_key_length: usize) -> &Self {
401 self.write()
402 .await
403 .set_max_header_key_length(max_header_key_length);
404 self
405 }
406
407 /// Sets the maximum length for a header value in bytes.
408 ///
409 /// # Arguments
410 ///
411 /// - `usize` - The maximum header value length.
412 ///
413 /// # Returns
414 ///
415 /// - `&Self` - The RequestConfig instance for chaining.
416 pub async fn max_header_value_length(&self, max_header_value_length: usize) -> &Self {
417 self.write()
418 .await
419 .set_max_header_value_length(max_header_value_length);
420 self
421 }
422
423 /// Sets the maximum size for request body in bytes.
424 ///
425 /// # Arguments
426 ///
427 /// - `usize` - The maximum body size.
428 ///
429 /// # Returns
430 ///
431 /// - `&Self` - The RequestConfig instance for chaining.
432 pub async fn max_body_size(&self, max_body_size: usize) -> &Self {
433 self.write().await.set_max_body_size(max_body_size);
434 self
435 }
436
437 /// Sets the maximum size for WebSocket frame in bytes.
438 ///
439 /// # Arguments
440 ///
441 /// - `usize` - The maximum WebSocket frame size.
442 ///
443 /// # Returns
444 ///
445 /// - `&Self` - The RequestConfig instance for chaining.
446 pub async fn max_ws_frame_size(&self, max_ws_frame_size: usize) -> &Self {
447 self.write().await.set_max_ws_frame_size(max_ws_frame_size);
448 self
449 }
450
451 /// Sets the maximum number of WebSocket frames to process in a single request.
452 ///
453 /// # Arguments
454 ///
455 /// - `usize` - The maximum WebSocket frames count.
456 ///
457 /// # Returns
458 ///
459 /// - `&Self` - The RequestConfig instance for chaining.
460 pub async fn max_ws_frames(&self, max_ws_frames: usize) -> &Self {
461 self.write().await.set_max_ws_frames(max_ws_frames);
462 self
463 }
464
465 /// Sets the timeout for reading HTTP request in milliseconds.
466 ///
467 /// # Arguments
468 ///
469 /// - `u64` - The HTTP read timeout in milliseconds.
470 ///
471 /// # Returns
472 ///
473 /// - `&Self` - The RequestConfig instance for chaining.
474 pub async fn http_read_timeout_ms(&self, http_read_timeout_ms: u64) -> &Self {
475 self.write()
476 .await
477 .set_http_read_timeout_ms(http_read_timeout_ms);
478 self
479 }
480
481 /// Sets the timeout for reading WebSocket frames in milliseconds.
482 ///
483 /// # Arguments
484 ///
485 /// - `u64` - The WebSocket read timeout in milliseconds.
486 ///
487 /// # Returns
488 ///
489 /// - `&Self` - The RequestConfig instance for chaining.
490 pub async fn ws_read_timeout_ms(&self, ws_read_timeout_ms: u64) -> &Self {
491 self.write()
492 .await
493 .set_ws_read_timeout_ms(ws_read_timeout_ms);
494 self
495 }
496}
497
498/// Provides a default value for `Request`.
499///
500/// Returns a new `Request` instance with all fields initialized to their default values.
501impl Default for Request {
502 #[inline(always)]
503 fn default() -> Self {
504 Self {
505 method: Method::default(),
506 host: String::new(),
507 version: HttpVersion::default(),
508 path: String::new(),
509 querys: hash_map_xx_hash3_64(),
510 headers: hash_map_xx_hash3_64(),
511 body: Vec::new(),
512 }
513 }
514}
515
516impl Request {
517 /// Parses a query string as_ref key-value pairs.
518 ///
519 /// Expects format "key1=value1&key2=value2". Empty values are allowed.
520 ///
521 /// # Arguments
522 ///
523 /// - `&str` - The query string to parse.
524 ///
525 /// # Returns
526 ///
527 /// - `HashMap<String, String>` - The parsed query parameters.
528 fn parse_querys<Q>(query: Q) -> RequestQuerys
529 where
530 Q: AsRef<str>,
531 {
532 let mut query_map: RequestQuerys = hash_map_xx_hash3_64();
533 for pair in query.as_ref().split(AND) {
534 if let Some((key, value)) = pair.split_once(EQUAL) {
535 if !key.is_empty() {
536 query_map.insert(key.to_string(), value.to_string());
537 }
538 } else if !pair.is_empty() {
539 query_map.insert(pair.to_string(), String::new());
540 }
541 }
542 query_map
543 }
544
545 /// Parses HTTP headers from a buffered reader.
546 ///
547 /// This method reads header lines from the provided buffered reader until an empty line
548 /// is encountered, which indicates the end of headers. It validates header count, length,
549 /// and content according to the provided configuration.
550 ///
551 /// # Arguments
552 ///
553 /// - `&mut R` - A mutable reference to a buffered reader implementing `AsyncBufReadExt`.
554 /// - `&RequestConfigData` - Configuration for security limits and buffer settings.
555 ///
556 /// # Returns
557 ///
558 /// - `Result<(RequestHeaders, RequestHost, usize), RequestError>` - A tuple containing:
559 /// - The parsed headers as a hash map
560 /// - The host value extracted from the Host header
561 /// - The content length extracted from the Content-Length header
562 /// - Or an error if parsing fails
563 async fn parse_headers<R>(
564 reader: &mut R,
565 config: &RequestConfigData,
566 ) -> Result<(RequestHeaders, RequestHost, usize), RequestError>
567 where
568 R: AsyncBufReadExt + Unpin,
569 {
570 let buffer_size: usize = config.get_buffer_size();
571 let max_header_line_length: usize = config.get_max_header_line_length();
572 let max_header_count: usize = config.get_max_header_count();
573 let max_header_key_length: usize = config.get_max_header_key_length();
574 let max_header_value_length: usize = config.get_max_header_value_length();
575 let max_body_size: usize = config.get_max_body_size();
576 let mut headers: RequestHeaders = hash_map_xx_hash3_64();
577 let mut host: RequestHost = String::new();
578 let mut content_length: usize = 0;
579 let mut header_count: usize = 0;
580 loop {
581 let header_line: &mut String = &mut String::with_capacity(buffer_size);
582 let bytes_read: usize = AsyncBufReadExt::read_line(reader, header_line)
583 .await
584 .map_err(|_| RequestError::HttpRead(HttpStatus::BadRequest))?;
585 if bytes_read > max_header_line_length {
586 return Err(RequestError::HeaderLineTooLong(
587 HttpStatus::RequestHeaderFieldsTooLarge,
588 ));
589 }
590 let header_line: &str = header_line.trim();
591 if header_line.is_empty() {
592 break;
593 }
594 header_count += 1;
595 if header_count > max_header_count {
596 return Err(RequestError::TooManyHeaders(
597 HttpStatus::RequestHeaderFieldsTooLarge,
598 ));
599 }
600 if let Some((key_part, value_part)) = header_line.split_once(COLON) {
601 let key: String = key_part.trim().to_ascii_lowercase();
602 if key.is_empty() {
603 continue;
604 }
605 if key.len() > max_header_key_length {
606 return Err(RequestError::HeaderKeyTooLong(
607 HttpStatus::RequestHeaderFieldsTooLarge,
608 ));
609 }
610 let value: String = value_part.trim().to_string();
611 if value.len() > max_header_value_length {
612 return Err(RequestError::HeaderValueTooLong(
613 HttpStatus::RequestHeaderFieldsTooLarge,
614 ));
615 }
616 if key == HOST {
617 host = value.clone();
618 } else if key == CONTENT_LENGTH {
619 match value.parse::<usize>() {
620 Ok(length) => {
621 if length > max_body_size {
622 return Err(RequestError::ContentLengthTooLarge(
623 HttpStatus::PayloadTooLarge,
624 ));
625 }
626 content_length = length;
627 }
628 Err(_) => {
629 return Err(RequestError::InvalidContentLength(HttpStatus::BadRequest));
630 }
631 }
632 }
633 headers.entry(key).or_default().push_back(value);
634 }
635 }
636 Ok((headers, host, content_length))
637 }
638
639 /// Parses an HTTP request from a TCP stream.
640 ///
641 /// Wraps the stream in a buffered reader and delegates to `http_from_reader`.
642 ///
643 /// # Arguments
644 ///
645 /// - `&ArcRwLock<TcpStream>` - The TCP stream to read from.
646 /// - `&RequestConfigData` - Configuration for security limits and buffer settings.
647 ///
648 /// # Returns
649 ///
650 /// - `Result<Request, RequestError>` - The parsed request or an error.
651 pub async fn http_from_stream(
652 stream: &ArcRwLockStream,
653 config: &RequestConfigData,
654 ) -> Result<Request, RequestError> {
655 let buffer_size: usize = config.get_buffer_size();
656 let max_request_line_length: usize = config.get_max_request_line_length();
657 let max_path_length: usize = config.get_max_path_length();
658 let max_query_length: usize = config.get_max_query_length();
659 let http_read_timeout_ms: u64 = config.get_http_read_timeout_ms();
660 timeout(Duration::from_millis(http_read_timeout_ms), async move {
661 let mut buf_stream: RwLockWriteGuard<'_, TcpStream> = stream.write().await;
662 let reader: &mut BufReader<&mut TcpStream> =
663 &mut BufReader::with_capacity(buffer_size, &mut buf_stream);
664 let mut request_line: String = String::with_capacity(buffer_size);
665 let bytes_read: usize = AsyncBufReadExt::read_line(reader, &mut request_line)
666 .await
667 .map_err(|_| RequestError::HttpRead(HttpStatus::BadRequest))?;
668 if bytes_read > max_request_line_length {
669 return Err(RequestError::RequestTooLong(HttpStatus::BadRequest));
670 }
671 let parts: Vec<&str> = request_line.split_whitespace().collect();
672 let parts_len: usize = parts.len();
673 if parts_len < 3 {
674 return Err(RequestError::HttpRequestPartsInsufficient(
675 HttpStatus::BadRequest,
676 ));
677 }
678 let method: RequestMethod = parts[0]
679 .parse::<RequestMethod>()
680 .unwrap_or(Method::Unknown(parts[0].to_string()));
681 let full_path: &str = parts[1];
682 if full_path.len() > max_path_length {
683 return Err(RequestError::PathTooLong(HttpStatus::URITooLong));
684 }
685 let full_path: RequestPath = full_path.to_string();
686 let version: RequestVersion = parts[2]
687 .parse::<RequestVersion>()
688 .unwrap_or(RequestVersion::Unknown(parts[2].to_string()));
689 let hash_index: Option<usize> = full_path.find(HASH);
690 let query_index: Option<usize> = full_path.find(QUERY);
691 let query_string: String = query_index.map_or_else(String::new, |i| {
692 let temp: &str = &full_path[i + 1..];
693 if hash_index.is_none() || hash_index.unwrap() <= i {
694 return temp.to_owned();
695 }
696 temp.split(HASH).next().unwrap_or_default().to_owned()
697 });
698 if query_string.len() > max_query_length {
699 return Err(RequestError::QueryTooLong(HttpStatus::URITooLong));
700 }
701 let querys: RequestQuerys = Self::parse_querys(&query_string);
702 let path: RequestPath = if let Some(i) = query_index.or(hash_index) {
703 full_path[..i].to_owned()
704 } else {
705 full_path.to_owned()
706 };
707 let (headers, host, content_length): (RequestHeaders, RequestHost, usize) =
708 Self::parse_headers(reader, config).await?;
709 let mut body: RequestBody = Vec::with_capacity(content_length);
710 if content_length > 0 {
711 body.resize(content_length, 0);
712 AsyncReadExt::read_exact(reader, &mut body)
713 .await
714 .map_err(|_| RequestError::ReadConnection(HttpStatus::BadRequest))?;
715 }
716 Ok(Request {
717 method,
718 host,
719 version,
720 path,
721 querys,
722 headers,
723 body,
724 })
725 })
726 .await
727 .map_err(|_| RequestError::ReadTimeout(HttpStatus::RequestTimeout))?
728 }
729
730 /// Parses a WebSocket request from a TCP stream.
731 ///
732 /// Wraps the stream in a buffered reader and delegates to `ws_from_reader`.
733 ///
734 /// # Arguments
735 ///
736 /// - `&ArcRwLock<TcpStream>` - The TCP stream to read from.
737 /// - `&RequestConfigData` - Configuration for security limits and buffer settings.
738 ///
739 /// # Returns
740 ///
741 /// - `Result<Request, RequestError>` - The parsed WebSocket request or an error.
742 pub async fn ws_from_stream(
743 &self,
744 stream: &ArcRwLockStream,
745 config: &RequestConfigData,
746 ) -> Result<Request, RequestError> {
747 let buffer_size: usize = config.get_buffer_size();
748 let max_ws_frame_size: usize = config.get_max_ws_frame_size();
749 let ws_read_timeout_ms: u64 = config.get_ws_read_timeout_ms();
750 let max_ws_frames: usize = config.get_max_ws_frames();
751 let mut dynamic_buffer: Vec<u8> = Vec::with_capacity(buffer_size);
752 let mut temp_buffer: Vec<u8> = vec![0; buffer_size];
753 let mut full_frame: Vec<u8> = Vec::with_capacity(max_ws_frame_size);
754 let mut frame_count: usize = 0;
755 let mut is_client_response: bool = false;
756 let ws_read_timeout_ms: u64 = (ws_read_timeout_ms >> 1) + (ws_read_timeout_ms & 1);
757 let timeout_duration: Duration = Duration::from_millis(ws_read_timeout_ms);
758 loop {
759 let len: usize = match timeout(
760 timeout_duration,
761 stream.write().await.read(&mut temp_buffer),
762 )
763 .await
764 {
765 Ok(result) => match result {
766 Ok(len) => len,
767 Err(error) => {
768 if error.kind() == ErrorKind::ConnectionReset
769 || error.kind() == ErrorKind::ConnectionAborted
770 {
771 return Err(RequestError::ClientDisconnected(HttpStatus::BadRequest));
772 }
773 return Err(RequestError::Unknown(HttpStatus::InternalServerError));
774 }
775 },
776 Err(_) => {
777 if !is_client_response {
778 return Err(RequestError::ReadTimeout(HttpStatus::RequestTimeout));
779 }
780 is_client_response = false;
781 stream
782 .try_send_body(&PING_FRAME)
783 .await
784 .map_err(|_| RequestError::WriteTimeout(HttpStatus::InternalServerError))?;
785 let _ = stream.try_flush().await;
786 continue;
787 }
788 };
789 if len == 0 {
790 return Err(RequestError::IncompleteWebSocketFrame(
791 HttpStatus::BadRequest,
792 ));
793 }
794 dynamic_buffer.extend_from_slice(&temp_buffer[..len]);
795 while let Some((frame, consumed)) = WebSocketFrame::decode_ws_frame(&dynamic_buffer) {
796 is_client_response = true;
797 dynamic_buffer.drain(0..consumed);
798 frame_count += 1;
799 if frame_count > max_ws_frames {
800 return Err(RequestError::TooManyHeaders(
801 HttpStatus::RequestHeaderFieldsTooLarge,
802 ));
803 }
804 match frame.get_opcode() {
805 WebSocketOpcode::Close => {
806 return Err(RequestError::ClientClosedConnection(HttpStatus::BadRequest));
807 }
808 WebSocketOpcode::Ping | WebSocketOpcode::Pong => {
809 continue;
810 }
811 WebSocketOpcode::Text | WebSocketOpcode::Binary => {
812 let payload_data: &[u8] = frame.get_payload_data();
813 if payload_data.len() > max_ws_frame_size {
814 return Err(RequestError::WebSocketFrameTooLarge(
815 HttpStatus::PayloadTooLarge,
816 ));
817 }
818 if full_frame.len() + payload_data.len() > max_ws_frame_size {
819 return Err(RequestError::WebSocketFrameTooLarge(
820 HttpStatus::PayloadTooLarge,
821 ));
822 }
823 full_frame.extend_from_slice(payload_data);
824 if *frame.get_fin() {
825 let mut request: Request = self.clone();
826 request.body = full_frame;
827 return Ok(request);
828 }
829 }
830 _ => {
831 return Err(RequestError::WebSocketOpcodeUnsupported(
832 HttpStatus::NotImplemented,
833 ));
834 }
835 }
836 }
837 }
838 }
839
840 /// Tries to get a query parameter value by key.
841 ///
842 /// The key type must implement AsRef<str> conversion.
843 ///
844 /// # Arguments
845 ///
846 /// - `AsRef<str>` - The query parameter key (implements AsRef<str>).
847 ///
848 /// # Returns
849 ///
850 /// - `Option<RequestQuerysValue>` - The parameter value if exists.
851 #[inline(always)]
852 pub fn try_get_query<K>(&self, key: K) -> Option<RequestQuerysValue>
853 where
854 K: AsRef<str>,
855 {
856 self.querys.get(key.as_ref()).cloned()
857 }
858
859 /// Gets a query parameter value by key.
860 ///
861 /// The key type must implement AsRef<str> conversion.
862 ///
863 /// # Arguments
864 ///
865 /// - `AsRef<str>` - The query parameter key (implements AsRef<str>).
866 ///
867 /// # Returns
868 ///
869 /// - `RequestQuerysValue` - The parameter value if exists.
870 ///
871 /// # Panics
872 ///
873 /// This function will panic if the query parameter key is not found.
874 #[inline(always)]
875 pub fn get_query<K>(&self, key: K) -> RequestQuerysValue
876 where
877 K: AsRef<str>,
878 {
879 self.try_get_query(key).unwrap()
880 }
881
882 /// Tries to retrieve the value of a request header by its key.
883 ///
884 /// # Arguments
885 ///
886 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
887 ///
888 /// # Returns
889 ///
890 /// - `Option<RequestHeadersValue>` - The optional header values.
891 #[inline(always)]
892 pub fn try_get_header<K>(&self, key: K) -> Option<RequestHeadersValue>
893 where
894 K: AsRef<str>,
895 {
896 self.headers.get(key.as_ref()).cloned()
897 }
898
899 /// Retrieves the value of a request header by its key.
900 ///
901 /// # Arguments
902 ///
903 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
904 ///
905 /// # Returns
906 ///
907 /// - `RequestHeadersValue` - The optional header values.
908 ///
909 /// # Panics
910 ///
911 /// This function will panic if the header key is not found.
912 #[inline(always)]
913 pub fn get_header<K>(&self, key: K) -> RequestHeadersValue
914 where
915 K: AsRef<str>,
916 {
917 self.try_get_header(key).unwrap()
918 }
919
920 /// Tries to retrieve the first value of a request header by its key.
921 ///
922 /// # Arguments
923 ///
924 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
925 ///
926 /// # Returns
927 ///
928 /// - `Option<RequestHeadersValueItem>` - The first header value if exists.
929 #[inline(always)]
930 pub fn try_get_header_front<K>(&self, key: K) -> Option<RequestHeadersValueItem>
931 where
932 K: AsRef<str>,
933 {
934 self.headers
935 .get(key.as_ref())
936 .and_then(|values| values.front().cloned())
937 }
938
939 /// Retrieves the first value of a request header by its key.
940 ///
941 /// # Arguments
942 ///
943 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
944 ///
945 /// # Returns
946 ///
947 /// - `RequestHeadersValueItem` - The first header value if exists.
948 ///
949 /// # Panics
950 ///
951 /// This function will panic if the header key is not found.
952 #[inline(always)]
953 pub fn get_header_front<K>(&self, key: K) -> RequestHeadersValueItem
954 where
955 K: AsRef<str>,
956 {
957 self.try_get_header_front(key).unwrap()
958 }
959
960 /// Tries to retrieve the last value of a request header by its key.
961 ///
962 /// # Arguments
963 ///
964 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
965 ///
966 /// # Returns
967 ///
968 /// - `Option<RequestHeadersValueItem>` - The last header value if exists.
969 #[inline(always)]
970 pub fn try_get_header_back<K>(&self, key: K) -> Option<RequestHeadersValueItem>
971 where
972 K: AsRef<str>,
973 {
974 self.headers
975 .get(key.as_ref())
976 .and_then(|values| values.back().cloned())
977 }
978
979 /// Retrieves the last value of a request header by its key.
980 ///
981 /// # Arguments
982 ///
983 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
984 ///
985 /// # Returns
986 ///
987 /// - `RequestHeadersValueItem` - The last header value if exists.
988 ///
989 /// # Panics
990 ///
991 /// This function will panic if the header key is not found.
992 #[inline(always)]
993 pub fn get_header_back<K>(&self, key: K) -> RequestHeadersValueItem
994 where
995 K: AsRef<str>,
996 {
997 self.try_get_header_back(key).unwrap()
998 }
999
1000 /// Tries to retrieve the number of values for a specific header.
1001 ///
1002 /// # Arguments
1003 ///
1004 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
1005 ///
1006 /// # Returns
1007 ///
1008 /// - `Option<usize>` - The count of values for the header if exists.
1009 #[inline(always)]
1010 pub fn try_get_header_length<K>(&self, key: K) -> Option<usize>
1011 where
1012 K: AsRef<str>,
1013 {
1014 self.headers.get(key.as_ref()).map(|values| values.len())
1015 }
1016
1017 /// Retrieves the number of values for a specific header.
1018 ///
1019 /// # Arguments
1020 ///
1021 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
1022 ///
1023 /// # Returns
1024 ///
1025 /// - `usize` - The count of values for the header.
1026 ///
1027 /// # Panics
1028 ///
1029 /// This function will panic if the header key is not found.
1030 #[inline(always)]
1031 pub fn get_header_length<K>(&self, key: K) -> usize
1032 where
1033 K: AsRef<str>,
1034 {
1035 self.try_get_header_length(key).unwrap()
1036 }
1037
1038 /// Retrieves the total number of header values across all headers.
1039 ///
1040 /// # Returns
1041 ///
1042 /// - `usize` - The total count of all header values.
1043 #[inline(always)]
1044 pub fn get_headers_values_length(&self) -> usize {
1045 self.headers.values().map(|values| values.len()).sum()
1046 }
1047
1048 /// Retrieves the number of unique headers.
1049 ///
1050 /// # Returns
1051 ///
1052 /// - `usize` - The count of unique header keys.
1053 #[inline(always)]
1054 pub fn get_headers_length(&self) -> usize {
1055 self.headers.len()
1056 }
1057
1058 /// Checks if a specific header exists.
1059 ///
1060 /// # Arguments
1061 ///
1062 /// - `AsRef<str>` - The header key to check (must implement AsRef<str>).
1063 ///
1064 /// # Returns
1065 ///
1066 /// - `bool` - Whether the header exists.
1067 #[inline(always)]
1068 pub fn has_header<K>(&self, key: K) -> bool
1069 where
1070 K: AsRef<str>,
1071 {
1072 self.headers.contains_key(key.as_ref())
1073 }
1074
1075 /// Checks if a header contains a specific value.
1076 ///
1077 /// # Arguments
1078 ///
1079 /// - `AsRef<str>` - The header key to check (must implement AsRef<str>).
1080 /// - `AsRef<str>` - The value to search for (must implement AsRef<str>).
1081 ///
1082 /// # Returns
1083 ///
1084 /// - `bool` - Whether the header contains the value.
1085 #[inline(always)]
1086 pub fn has_header_value<K, V>(&self, key: K, value: V) -> bool
1087 where
1088 K: AsRef<str>,
1089 V: AsRef<str>,
1090 {
1091 if let Some(values) = self.headers.get(key.as_ref()) {
1092 values.contains(&value.as_ref().to_owned())
1093 } else {
1094 false
1095 }
1096 }
1097
1098 /// Retrieves the body content of the request as a UTF-8 encoded string.
1099 ///
1100 /// This method uses `String::from_utf8_lossy` to convert the byte slice returned by `self.get_body()` as_ref a string.
1101 /// If the byte slice contains invalid UTF-8 sequences, they will be replaced with the Unicode replacement character ().
1102 ///
1103 /// # Returns
1104 ///
1105 /// - `String` - The body content as a string.
1106 #[inline(always)]
1107 pub fn get_body_string(&self) -> String {
1108 String::from_utf8_lossy(self.get_body()).into_owned()
1109 }
1110
1111 /// Deserializes the body content of the request as_ref a specified type `T`.
1112 ///
1113 /// This method first retrieves the body content as a byte slice using `self.get_body()`.
1114 /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
1115 ///
1116 /// # Arguments
1117 ///
1118 /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
1119 ///
1120 /// # Returns
1121 ///
1122 /// - `Result<T, serde_json::Error>` - The deserialization result.
1123 pub fn try_get_body_json<T>(&self) -> Result<T, serde_json::Error>
1124 where
1125 T: DeserializeOwned,
1126 {
1127 serde_json::from_slice(self.get_body())
1128 }
1129
1130 /// Deserializes the body content of the request as_ref a specified type `T`.
1131 ///
1132 /// This method first retrieves the body content as a byte slice using `self.get_body()`.
1133 /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
1134 ///
1135 /// # Arguments
1136 ///
1137 /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
1138 ///
1139 /// # Returns
1140 ///
1141 /// - `T` - The deserialized body content.
1142 ///
1143 /// # Panics
1144 ///
1145 /// This function will panic if the deserialization fails.
1146 pub fn get_body_json<T>(&self) -> T
1147 where
1148 T: DeserializeOwned,
1149 {
1150 self.try_get_body_json().unwrap()
1151 }
1152
1153 /// Converts the request to a formatted string representation.
1154 ///
1155 /// This method provides a human-readable summary of the request, including its method,
1156 /// host, version, path, query parameters, headers, and body information.
1157 ///
1158 /// # Returns
1159 ///
1160 /// - `String` - The formatted request details.
1161 #[inline(always)]
1162 pub fn get_string(&self) -> String {
1163 let body: &Vec<u8> = self.get_body();
1164 let body_type: &'static str = if std::str::from_utf8(body).is_ok() {
1165 PLAIN
1166 } else {
1167 BINARY
1168 };
1169 format!(
1170 "[Request] => [method]: {}; [host]: {}; [version]: {}; [path]: {}; [querys]: {:?}; [headers]: {:?}; [body]: {} bytes {};",
1171 self.get_method(),
1172 self.get_host(),
1173 self.get_version(),
1174 self.get_path(),
1175 self.get_querys(),
1176 self.get_headers(),
1177 body.len(),
1178 body_type
1179 )
1180 }
1181
1182 /// Retrieves the upgrade type from the request headers.
1183 ///
1184 /// This method looks for the `UPGRADE` header and attempts to parse its value
1185 /// as_ref an `UpgradeType`. If the header is missing or the value is invalid,
1186 /// it returns the default `UpgradeType`.
1187 ///
1188 /// # Returns
1189 ///
1190 /// - `UpgradeType` - The parsed upgrade type.
1191 #[inline(always)]
1192 pub fn get_upgrade_type(&self) -> UpgradeType {
1193 let upgrade_type: UpgradeType = self
1194 .try_get_header_back(UPGRADE)
1195 .and_then(|data| data.parse::<UpgradeType>().ok())
1196 .unwrap_or_default();
1197 upgrade_type
1198 }
1199
1200 /// Checks whether the WebSocket upgrade is enabled for this request.
1201 ///
1202 /// This method determines if the `UPGRADE` header indicates a WebSocket connection.
1203 ///
1204 /// # Returns
1205 ///
1206 /// - `bool` - Whether WebSocket upgrade is enabled.
1207 #[inline(always)]
1208 pub fn is_ws(&self) -> bool {
1209 self.get_upgrade_type().is_ws()
1210 }
1211
1212 /// Checks if the current upgrade type is HTTP/2 cleartext (h2c).
1213 ///
1214 /// # Returns
1215 ///
1216 /// - `bool` - Whether the upgrade type is h2c.
1217 #[inline(always)]
1218 pub fn is_h2c(&self) -> bool {
1219 self.get_upgrade_type().is_h2c()
1220 }
1221
1222 /// Checks if the current upgrade type is TLS (any version).
1223 ///
1224 /// # Returns
1225 ///
1226 /// - `bool` - Whether the upgrade type is TLS.
1227 #[inline(always)]
1228 pub fn is_tls(&self) -> bool {
1229 self.get_upgrade_type().is_tls()
1230 }
1231
1232 /// Checks whether the upgrade type is unknown.
1233 ///
1234 /// # Returns
1235 ///
1236 /// - `bool` - Whether the upgrade type is unknown.
1237 #[inline(always)]
1238 pub fn is_unknown_upgrade(&self) -> bool {
1239 self.get_upgrade_type().is_unknown()
1240 }
1241
1242 /// Checks if the HTTP version is HTTP/1.1 or higher.
1243 ///
1244 /// # Returns
1245 ///
1246 /// - `bool` - Whether the version is HTTP/1.1 or higher.
1247 #[inline(always)]
1248 pub fn is_http1_1_or_higher(&self) -> bool {
1249 self.get_version().is_http1_1_or_higher()
1250 }
1251
1252 /// Checks whether the HTTP version is HTTP/0.9.
1253 ///
1254 /// # Returns
1255 ///
1256 /// - `bool` - Whether the version is HTTP/0.9.
1257 #[inline(always)]
1258 pub fn is_http0_9(&self) -> bool {
1259 self.get_version().is_http0_9()
1260 }
1261
1262 /// Checks whether the HTTP version is HTTP/1.0.
1263 ///
1264 /// # Returns
1265 ///
1266 /// - `bool` - Whether the version is HTTP/1.0.
1267 #[inline(always)]
1268 pub fn is_http1_0(&self) -> bool {
1269 self.get_version().is_http1_0()
1270 }
1271
1272 /// Checks whether the HTTP version is HTTP/1.1.
1273 ///
1274 /// # Returns
1275 ///
1276 /// - `bool` - Whether the version is HTTP/1.1.
1277 #[inline(always)]
1278 pub fn is_http1_1(&self) -> bool {
1279 self.get_version().is_http1_1()
1280 }
1281
1282 /// Checks whether the HTTP version is HTTP/2.
1283 ///
1284 /// # Returns
1285 ///
1286 /// - `bool` - Whether the version is HTTP/2.
1287 #[inline(always)]
1288 pub fn is_http2(&self) -> bool {
1289 self.get_version().is_http2()
1290 }
1291
1292 /// Checks whether the HTTP version is HTTP/3.
1293 ///
1294 /// # Returns
1295 ///
1296 /// - `bool` - Whether the version is HTTP/3.
1297 #[inline(always)]
1298 pub fn is_http3(&self) -> bool {
1299 self.get_version().is_http3()
1300 }
1301
1302 /// Checks whether the HTTP version is unknown.
1303 ///
1304 /// # Returns
1305 ///
1306 /// - `bool` - Whether the version is unknown.
1307 #[inline(always)]
1308 pub fn is_unknown_version(&self) -> bool {
1309 self.get_version().is_unknown()
1310 }
1311
1312 /// Checks whether the version belongs to the HTTP family.
1313 ///
1314 /// # Returns
1315 ///
1316 /// - `bool` - Whether the version is HTTP.
1317 #[inline(always)]
1318 pub fn is_http(&self) -> bool {
1319 self.get_version().is_http()
1320 }
1321
1322 /// Checks whether the request method is GET.
1323 ///
1324 /// # Returns
1325 ///
1326 /// - `bool` - Whether the method is GET.
1327 #[inline(always)]
1328 pub fn is_get(&self) -> bool {
1329 self.get_method().is_get()
1330 }
1331
1332 /// Checks whether the request method is POST.
1333 ///
1334 /// # Returns
1335 ///
1336 /// - `bool` - Whether the method is POST.
1337 #[inline(always)]
1338 pub fn is_post(&self) -> bool {
1339 self.get_method().is_post()
1340 }
1341
1342 /// Checks whether the request method is PUT.
1343 ///
1344 /// # Returns
1345 ///
1346 /// - `bool` - Whether the method is PUT.
1347 #[inline(always)]
1348 pub fn is_put(&self) -> bool {
1349 self.get_method().is_put()
1350 }
1351
1352 /// Checks whether the request method is DELETE.
1353 ///
1354 /// # Returns
1355 ///
1356 /// - `bool` - Whether the method is DELETE.
1357 #[inline(always)]
1358 pub fn is_delete(&self) -> bool {
1359 self.get_method().is_delete()
1360 }
1361
1362 /// Checks whether the request method is PATCH.
1363 ///
1364 /// # Returns
1365 ///
1366 /// - `bool` - Whether the method is PATCH.
1367 #[inline(always)]
1368 pub fn is_patch(&self) -> bool {
1369 self.get_method().is_patch()
1370 }
1371
1372 /// Checks whether the request method is HEAD.
1373 ///
1374 /// # Returns
1375 ///
1376 /// - `bool` - Whether the method is HEAD.
1377 #[inline(always)]
1378 pub fn is_head(&self) -> bool {
1379 self.get_method().is_head()
1380 }
1381
1382 /// Checks whether the request method is OPTIONS.
1383 ///
1384 /// # Returns
1385 ///
1386 /// - `bool` - Whether the method is OPTIONS.
1387 #[inline(always)]
1388 pub fn is_options(&self) -> bool {
1389 self.get_method().is_options()
1390 }
1391
1392 /// Checks whether the request method is CONNECT.
1393 ///
1394 /// # Returns
1395 ///
1396 /// - `bool` - Whether the method is CONNECT.
1397 #[inline(always)]
1398 pub fn is_connect(&self) -> bool {
1399 self.get_method().is_connect()
1400 }
1401
1402 /// Checks whether the request method is TRACE.
1403 ///
1404 /// # Returns
1405 ///
1406 /// - `bool` - Whether the method is TRACE.
1407 #[inline(always)]
1408 pub fn is_trace(&self) -> bool {
1409 self.get_method().is_trace()
1410 }
1411
1412 /// Checks whether the request method is UNKNOWN.
1413 ///
1414 /// # Returns
1415 ///
1416 /// - `bool` - Whether the method is UNKNOWN.
1417 #[inline(always)]
1418 pub fn is_unknown_method(&self) -> bool {
1419 self.get_method().is_unknown()
1420 }
1421
1422 /// Determines if a keep-alive connection should be enabled for this request.
1423 ///
1424 /// This function checks the `Connection` header and the HTTP version to determine
1425 /// if keep-alive should be enabled. The logic is as follows:
1426 ///
1427 /// 1. If the `Connection` header exists:
1428 /// - Returns `true` if the header value is "keep-alive" (case-insensitive).
1429 /// - Returns `false` if the header value is "close" (case-insensitive).
1430 /// 2. If no `Connection` header is present:
1431 /// - Returns `true` if the HTTP version is 1.1 or higher.
1432 /// - Returns `false` otherwise.
1433 ///
1434 /// # Returns
1435 ///
1436 /// - `bool` - Whether keep-alive should be enabled.
1437 #[inline(always)]
1438 pub fn is_enable_keep_alive(&self) -> bool {
1439 if let Some(connection_value) = self.try_get_header_back(CONNECTION) {
1440 if connection_value.eq_ignore_ascii_case(KEEP_ALIVE) {
1441 return true;
1442 } else if connection_value.eq_ignore_ascii_case(CLOSE) {
1443 return self.is_ws();
1444 }
1445 }
1446 self.is_http1_1_or_higher() || self.is_ws()
1447 }
1448
1449 /// Determines if keep-alive should be disabled for this request.
1450 ///
1451 /// # Returns
1452 ///
1453 /// - `bool` - Whether keep-alive should be disabled.
1454 #[inline(always)]
1455 pub fn is_disable_keep_alive(&self) -> bool {
1456 !self.is_enable_keep_alive()
1457 }
1458}