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