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