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 /// - `&RequestConfigData` - 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: &RequestConfigData,
532 ) -> Result<(RequestHeaders, RequestHost, usize), RequestError>
533 where
534 R: AsyncBufReadExt + Unpin,
535 {
536 let buffer_size: usize = config.get_buffer_size();
537 let max_header_line_length: usize = config.get_max_header_line_length();
538 let max_header_count: usize = config.get_max_header_count();
539 let max_header_key_length: usize = config.get_max_header_key_length();
540 let max_header_value_length: usize = config.get_max_header_value_length();
541 let max_body_size: usize = config.get_max_body_size();
542 let mut headers: RequestHeaders = hash_map_xx_hash3_64();
543 let mut host: RequestHost = String::new();
544 let mut content_length: usize = 0;
545 let mut header_count: usize = 0;
546 loop {
547 let header_line: &mut String = &mut String::with_capacity(buffer_size);
548 let bytes_read: usize = AsyncBufReadExt::read_line(reader, header_line)
549 .await
550 .map_err(|_| RequestError::HttpRead(HttpStatus::BadRequest))?;
551 if bytes_read > max_header_line_length {
552 return Err(RequestError::HeaderLineTooLong(
553 HttpStatus::RequestHeaderFieldsTooLarge,
554 ));
555 }
556 let header_line: &str = header_line.trim();
557 if header_line.is_empty() {
558 break;
559 }
560 header_count += 1;
561 if header_count > max_header_count {
562 return Err(RequestError::TooManyHeaders(
563 HttpStatus::RequestHeaderFieldsTooLarge,
564 ));
565 }
566 if let Some((key_part, value_part)) = header_line.split_once(COLON) {
567 let key: String = key_part.trim().to_ascii_lowercase();
568 if key.is_empty() {
569 continue;
570 }
571 if key.len() > max_header_key_length {
572 return Err(RequestError::HeaderKeyTooLong(
573 HttpStatus::RequestHeaderFieldsTooLarge,
574 ));
575 }
576 let value: String = value_part.trim().to_string();
577 if value.len() > max_header_value_length {
578 return Err(RequestError::HeaderValueTooLong(
579 HttpStatus::RequestHeaderFieldsTooLarge,
580 ));
581 }
582 if key == HOST {
583 host = value.clone();
584 } else if key == CONTENT_LENGTH {
585 match value.parse::<usize>() {
586 Ok(length) => {
587 if length > max_body_size {
588 return Err(RequestError::ContentLengthTooLarge(
589 HttpStatus::PayloadTooLarge,
590 ));
591 }
592 content_length = length;
593 }
594 Err(_) => {
595 return Err(RequestError::InvalidContentLength(HttpStatus::BadRequest));
596 }
597 }
598 }
599 headers.entry(key).or_default().push_back(value);
600 }
601 }
602 Ok((headers, host, content_length))
603 }
604
605 /// Parses an HTTP request from a TCP stream.
606 ///
607 /// Wraps the stream in a buffered reader and delegates to `http_from_reader`.
608 ///
609 /// # Arguments
610 ///
611 /// - `&ArcRwLock<TcpStream>` - The TCP stream to read from.
612 /// - `&RequestConfigData` - Configuration for security limits and buffer settings.
613 ///
614 /// # Returns
615 ///
616 /// - `Result<Request, RequestError>` - The parsed request or an error.
617 pub async fn http_from_stream(
618 stream: &ArcRwLockStream,
619 config: &RequestConfigData,
620 ) -> Result<Request, RequestError> {
621 let buffer_size: usize = config.get_buffer_size();
622 let max_request_line_length: usize = config.get_max_request_line_length();
623 let max_path_length: usize = config.get_max_path_length();
624 let max_query_length: usize = config.get_max_query_length();
625 let http_read_timeout_ms: u64 = config.get_http_read_timeout_ms();
626 timeout(Duration::from_millis(http_read_timeout_ms), async move {
627 let mut buf_stream: RwLockWriteGuard<'_, TcpStream> = stream.write().await;
628 let reader: &mut BufReader<&mut TcpStream> =
629 &mut BufReader::with_capacity(buffer_size, &mut buf_stream);
630 let mut request_line: String = String::with_capacity(buffer_size);
631 let bytes_read: usize = AsyncBufReadExt::read_line(reader, &mut request_line)
632 .await
633 .map_err(|_| RequestError::HttpRead(HttpStatus::BadRequest))?;
634 if bytes_read > max_request_line_length {
635 return Err(RequestError::RequestTooLong(HttpStatus::BadRequest));
636 }
637 let parts: Vec<&str> = request_line.split_whitespace().collect();
638 let parts_len: usize = parts.len();
639 if parts_len < 3 {
640 return Err(RequestError::HttpRequestPartsInsufficient(
641 HttpStatus::BadRequest,
642 ));
643 }
644 let method: RequestMethod = parts[0]
645 .parse::<RequestMethod>()
646 .unwrap_or(Method::Unknown(parts[0].to_string()));
647 let full_path: &str = parts[1];
648 if full_path.len() > max_path_length {
649 return Err(RequestError::PathTooLong(HttpStatus::URITooLong));
650 }
651 let full_path: RequestPath = full_path.to_string();
652 let version: RequestVersion = parts[2]
653 .parse::<RequestVersion>()
654 .unwrap_or(RequestVersion::Unknown(parts[2].to_string()));
655 let hash_index: Option<usize> = full_path.find(HASH);
656 let query_index: Option<usize> = full_path.find(QUERY);
657 let query_string: String = query_index.map_or_else(String::new, |i| {
658 let temp: &str = &full_path[i + 1..];
659 if hash_index.is_none() || hash_index.unwrap() <= i {
660 return temp.to_owned();
661 }
662 temp.split(HASH).next().unwrap_or_default().to_owned()
663 });
664 if query_string.len() > max_query_length {
665 return Err(RequestError::QueryTooLong(HttpStatus::URITooLong));
666 }
667 let querys: RequestQuerys = Self::parse_querys(&query_string);
668 let path: RequestPath = if let Some(i) = query_index.or(hash_index) {
669 full_path[..i].to_owned()
670 } else {
671 full_path.to_owned()
672 };
673 let (headers, host, content_length): (RequestHeaders, RequestHost, usize) =
674 Self::parse_headers(reader, config).await?;
675 let mut body: RequestBody = Vec::with_capacity(content_length);
676 if content_length > 0 {
677 body.resize(content_length, 0);
678 AsyncReadExt::read_exact(reader, &mut body)
679 .await
680 .map_err(|_| RequestError::ReadConnection(HttpStatus::BadRequest))?;
681 }
682 Ok(Request {
683 method,
684 host,
685 version,
686 path,
687 querys,
688 headers,
689 body,
690 })
691 })
692 .await
693 .map_err(|_| RequestError::ReadTimeout(HttpStatus::RequestTimeout))?
694 }
695
696 /// Parses a WebSocket request from a TCP stream.
697 ///
698 /// Wraps the stream in a buffered reader and delegates to `ws_from_reader`.
699 ///
700 /// # Arguments
701 ///
702 /// - `&ArcRwLock<TcpStream>` - The TCP stream to read from.
703 /// - `&RequestConfigData` - Configuration for security limits and buffer settings.
704 ///
705 /// # Returns
706 ///
707 /// - `Result<Request, RequestError>` - The parsed WebSocket request or an error.
708 pub async fn ws_from_stream(
709 &self,
710 stream: &ArcRwLockStream,
711 config: &RequestConfigData,
712 ) -> Result<Request, RequestError> {
713 let buffer_size: usize = config.get_buffer_size();
714 let max_ws_frame_size: usize = config.get_max_ws_frame_size();
715 let ws_read_timeout_ms: u64 = config.get_ws_read_timeout_ms();
716 let max_ws_frames: usize = config.get_max_ws_frames();
717 let mut dynamic_buffer: Vec<u8> = Vec::with_capacity(buffer_size);
718 let mut temp_buffer: Vec<u8> = vec![0; buffer_size];
719 let mut full_frame: Vec<u8> = Vec::with_capacity(max_ws_frame_size);
720 let mut frame_count: usize = 0;
721 let mut is_client_response: bool = false;
722 let ws_read_timeout_ms: u64 = (ws_read_timeout_ms >> 1) + (ws_read_timeout_ms & 1);
723 let timeout_duration: Duration = Duration::from_millis(ws_read_timeout_ms);
724 loop {
725 let len: usize = match timeout(
726 timeout_duration,
727 stream.write().await.read(&mut temp_buffer),
728 )
729 .await
730 {
731 Ok(result) => match result {
732 Ok(len) => len,
733 Err(error) => {
734 if error.kind() == ErrorKind::ConnectionReset
735 || error.kind() == ErrorKind::ConnectionAborted
736 {
737 return Err(RequestError::ClientDisconnected(HttpStatus::BadRequest));
738 }
739 return Err(RequestError::Unknown(HttpStatus::InternalServerError));
740 }
741 },
742 Err(_) => {
743 if !is_client_response {
744 return Err(RequestError::ReadTimeout(HttpStatus::RequestTimeout));
745 }
746 is_client_response = false;
747 stream
748 .try_send_body(&PING_FRAME)
749 .await
750 .map_err(|_| RequestError::WriteTimeout(HttpStatus::InternalServerError))?;
751 let _ = stream.try_flush().await;
752 continue;
753 }
754 };
755 if len == 0 {
756 return Err(RequestError::IncompleteWebSocketFrame(
757 HttpStatus::BadRequest,
758 ));
759 }
760 dynamic_buffer.extend_from_slice(&temp_buffer[..len]);
761 while let Some((frame, consumed)) = WebSocketFrame::decode_ws_frame(&dynamic_buffer) {
762 is_client_response = true;
763 dynamic_buffer.drain(0..consumed);
764 frame_count += 1;
765 if frame_count > max_ws_frames {
766 return Err(RequestError::TooManyHeaders(
767 HttpStatus::RequestHeaderFieldsTooLarge,
768 ));
769 }
770 match frame.get_opcode() {
771 WebSocketOpcode::Close => {
772 return Err(RequestError::ClientClosedConnection(HttpStatus::BadRequest));
773 }
774 WebSocketOpcode::Ping | WebSocketOpcode::Pong => {
775 continue;
776 }
777 WebSocketOpcode::Text | WebSocketOpcode::Binary => {
778 let payload_data: &[u8] = frame.get_payload_data();
779 if payload_data.len() > max_ws_frame_size {
780 return Err(RequestError::WebSocketFrameTooLarge(
781 HttpStatus::PayloadTooLarge,
782 ));
783 }
784 if full_frame.len() + payload_data.len() > max_ws_frame_size {
785 return Err(RequestError::WebSocketFrameTooLarge(
786 HttpStatus::PayloadTooLarge,
787 ));
788 }
789 full_frame.extend_from_slice(payload_data);
790 if *frame.get_fin() {
791 let mut request: Request = self.clone();
792 request.body = full_frame;
793 return Ok(request);
794 }
795 }
796 _ => {
797 return Err(RequestError::WebSocketOpcodeUnsupported(
798 HttpStatus::NotImplemented,
799 ));
800 }
801 }
802 }
803 }
804 }
805
806 /// Tries to get a query parameter value by key.
807 ///
808 /// The key type must implement AsRef<str> conversion.
809 ///
810 /// # Arguments
811 ///
812 /// - `AsRef<str>` - The query parameter key (implements AsRef<str>).
813 ///
814 /// # Returns
815 ///
816 /// - `Option<RequestQuerysValue>` - The parameter value if exists.
817 #[inline(always)]
818 pub fn try_get_query<K>(&self, key: K) -> Option<RequestQuerysValue>
819 where
820 K: AsRef<str>,
821 {
822 self.querys.get(key.as_ref()).cloned()
823 }
824
825 /// Gets a query parameter value by key.
826 ///
827 /// The key type must implement AsRef<str> conversion.
828 ///
829 /// # Arguments
830 ///
831 /// - `AsRef<str>` - The query parameter key (implements AsRef<str>).
832 ///
833 /// # Returns
834 ///
835 /// - `RequestQuerysValue` - The parameter value if exists.
836 ///
837 /// # Panics
838 ///
839 /// This function will panic if the query parameter key is not found.
840 #[inline(always)]
841 pub fn get_query<K>(&self, key: K) -> RequestQuerysValue
842 where
843 K: AsRef<str>,
844 {
845 self.try_get_query(key).unwrap()
846 }
847
848 /// Tries to retrieve the value of a request header by its key.
849 ///
850 /// # Arguments
851 ///
852 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
853 ///
854 /// # Returns
855 ///
856 /// - `Option<RequestHeadersValue>` - The optional header values.
857 #[inline(always)]
858 pub fn try_get_header<K>(&self, key: K) -> Option<RequestHeadersValue>
859 where
860 K: AsRef<str>,
861 {
862 self.headers.get(key.as_ref()).cloned()
863 }
864
865 /// Retrieves the value of a request header by its key.
866 ///
867 /// # Arguments
868 ///
869 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
870 ///
871 /// # Returns
872 ///
873 /// - `RequestHeadersValue` - The optional header values.
874 ///
875 /// # Panics
876 ///
877 /// This function will panic if the header key is not found.
878 #[inline(always)]
879 pub fn get_header<K>(&self, key: K) -> RequestHeadersValue
880 where
881 K: AsRef<str>,
882 {
883 self.try_get_header(key).unwrap()
884 }
885
886 /// Tries to retrieve the first value of a request header by its key.
887 ///
888 /// # Arguments
889 ///
890 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
891 ///
892 /// # Returns
893 ///
894 /// - `Option<RequestHeadersValueItem>` - The first header value if exists.
895 #[inline(always)]
896 pub fn try_get_header_front<K>(&self, key: K) -> Option<RequestHeadersValueItem>
897 where
898 K: AsRef<str>,
899 {
900 self.headers
901 .get(key.as_ref())
902 .and_then(|values| values.front().cloned())
903 }
904
905 /// Retrieves the first value of a request header by its key.
906 ///
907 /// # Arguments
908 ///
909 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
910 ///
911 /// # Returns
912 ///
913 /// - `RequestHeadersValueItem` - The first header value if exists.
914 ///
915 /// # Panics
916 ///
917 /// This function will panic if the header key is not found.
918 #[inline(always)]
919 pub fn get_header_front<K>(&self, key: K) -> RequestHeadersValueItem
920 where
921 K: AsRef<str>,
922 {
923 self.try_get_header_front(key).unwrap()
924 }
925
926 /// Tries to retrieve the last value of a request header by its key.
927 ///
928 /// # Arguments
929 ///
930 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
931 ///
932 /// # Returns
933 ///
934 /// - `Option<RequestHeadersValueItem>` - The last header value if exists.
935 #[inline(always)]
936 pub fn try_get_header_back<K>(&self, key: K) -> Option<RequestHeadersValueItem>
937 where
938 K: AsRef<str>,
939 {
940 self.headers
941 .get(key.as_ref())
942 .and_then(|values| values.back().cloned())
943 }
944
945 /// Retrieves the last value of a request header by its key.
946 ///
947 /// # Arguments
948 ///
949 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
950 ///
951 /// # Returns
952 ///
953 /// - `RequestHeadersValueItem` - The last header value if exists.
954 ///
955 /// # Panics
956 ///
957 /// This function will panic if the header key is not found.
958 #[inline(always)]
959 pub fn get_header_back<K>(&self, key: K) -> RequestHeadersValueItem
960 where
961 K: AsRef<str>,
962 {
963 self.try_get_header_back(key).unwrap()
964 }
965
966 /// Tries to retrieve the number of values for a specific header.
967 ///
968 /// # Arguments
969 ///
970 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
971 ///
972 /// # Returns
973 ///
974 /// - `Option<usize>` - The count of values for the header if exists.
975 #[inline(always)]
976 pub fn try_get_header_length<K>(&self, key: K) -> Option<usize>
977 where
978 K: AsRef<str>,
979 {
980 self.headers.get(key.as_ref()).map(|values| values.len())
981 }
982
983 /// Retrieves the number of values for a specific header.
984 ///
985 /// # Arguments
986 ///
987 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
988 ///
989 /// # Returns
990 ///
991 /// - `usize` - The count of values for the header.
992 ///
993 /// # Panics
994 ///
995 /// This function will panic if the header key is not found.
996 #[inline(always)]
997 pub fn get_header_length<K>(&self, key: K) -> usize
998 where
999 K: AsRef<str>,
1000 {
1001 self.try_get_header_length(key).unwrap()
1002 }
1003
1004 /// Retrieves the total number of header values across all headers.
1005 ///
1006 /// # Returns
1007 ///
1008 /// - `usize` - The total count of all header values.
1009 #[inline(always)]
1010 pub fn get_headers_values_length(&self) -> usize {
1011 self.headers.values().map(|values| values.len()).sum()
1012 }
1013
1014 /// Retrieves the number of unique headers.
1015 ///
1016 /// # Returns
1017 ///
1018 /// - `usize` - The count of unique header keys.
1019 #[inline(always)]
1020 pub fn get_headers_length(&self) -> usize {
1021 self.headers.len()
1022 }
1023
1024 /// Checks if a specific header exists.
1025 ///
1026 /// # Arguments
1027 ///
1028 /// - `AsRef<str>` - The header key to check (must implement AsRef<str>).
1029 ///
1030 /// # Returns
1031 ///
1032 /// - `bool` - Whether the header exists.
1033 #[inline(always)]
1034 pub fn has_header<K>(&self, key: K) -> bool
1035 where
1036 K: AsRef<str>,
1037 {
1038 self.headers.contains_key(key.as_ref())
1039 }
1040
1041 /// Checks if a header contains a specific value.
1042 ///
1043 /// # Arguments
1044 ///
1045 /// - `AsRef<str>` - The header key to check (must implement AsRef<str>).
1046 /// - `AsRef<str>` - The value to search for (must implement AsRef<str>).
1047 ///
1048 /// # Returns
1049 ///
1050 /// - `bool` - Whether the header contains the value.
1051 #[inline(always)]
1052 pub fn has_header_value<K, V>(&self, key: K, value: V) -> bool
1053 where
1054 K: AsRef<str>,
1055 V: AsRef<str>,
1056 {
1057 if let Some(values) = self.headers.get(key.as_ref()) {
1058 values.contains(&value.as_ref().to_owned())
1059 } else {
1060 false
1061 }
1062 }
1063
1064 /// Retrieves the body content of the request as a UTF-8 encoded string.
1065 ///
1066 /// This method uses `String::from_utf8_lossy` to convert the byte slice returned by `self.get_body()` as_ref a string.
1067 /// If the byte slice contains invalid UTF-8 sequences, they will be replaced with the Unicode replacement character ().
1068 ///
1069 /// # Returns
1070 ///
1071 /// - `String` - The body content as a string.
1072 #[inline(always)]
1073 pub fn get_body_string(&self) -> String {
1074 String::from_utf8_lossy(self.get_body()).into_owned()
1075 }
1076
1077 /// Deserializes the body content of the request as_ref a specified type `T`.
1078 ///
1079 /// This method first retrieves the body content as a byte slice using `self.get_body()`.
1080 /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
1081 ///
1082 /// # Arguments
1083 ///
1084 /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
1085 ///
1086 /// # Returns
1087 ///
1088 /// - `Result<T, serde_json::Error>` - The deserialization result.
1089 pub fn try_get_body_json<T>(&self) -> Result<T, serde_json::Error>
1090 where
1091 T: DeserializeOwned,
1092 {
1093 serde_json::from_slice(self.get_body())
1094 }
1095
1096 /// Deserializes the body content of the request as_ref a specified type `T`.
1097 ///
1098 /// This method first retrieves the body content as a byte slice using `self.get_body()`.
1099 /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
1100 ///
1101 /// # Arguments
1102 ///
1103 /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
1104 ///
1105 /// # Returns
1106 ///
1107 /// - `T` - The deserialized body content.
1108 ///
1109 /// # Panics
1110 ///
1111 /// This function will panic if the deserialization fails.
1112 pub fn get_body_json<T>(&self) -> T
1113 where
1114 T: DeserializeOwned,
1115 {
1116 self.try_get_body_json().unwrap()
1117 }
1118
1119 /// Converts the request to a formatted string representation.
1120 ///
1121 /// This method provides a human-readable summary of the request, including its method,
1122 /// host, version, path, query parameters, headers, and body information.
1123 ///
1124 /// # Returns
1125 ///
1126 /// - `String` - The formatted request details.
1127 #[inline(always)]
1128 pub fn get_string(&self) -> String {
1129 let body: &Vec<u8> = self.get_body();
1130 let body_type: &'static str = if std::str::from_utf8(body).is_ok() {
1131 PLAIN
1132 } else {
1133 BINARY
1134 };
1135 format!(
1136 "[Request] => [method]: {}; [host]: {}; [version]: {}; [path]: {}; [querys]: {:?}; [headers]: {:?}; [body]: {} bytes {};",
1137 self.get_method(),
1138 self.get_host(),
1139 self.get_version(),
1140 self.get_path(),
1141 self.get_querys(),
1142 self.get_headers(),
1143 body.len(),
1144 body_type
1145 )
1146 }
1147
1148 /// Retrieves the upgrade type from the request headers.
1149 ///
1150 /// This method looks for the `UPGRADE` header and attempts to parse its value
1151 /// as_ref an `UpgradeType`. If the header is missing or the value is invalid,
1152 /// it returns the default `UpgradeType`.
1153 ///
1154 /// # Returns
1155 ///
1156 /// - `UpgradeType` - The parsed upgrade type.
1157 #[inline(always)]
1158 pub fn get_upgrade_type(&self) -> UpgradeType {
1159 let upgrade_type: UpgradeType = self
1160 .try_get_header_back(UPGRADE)
1161 .and_then(|data| data.parse::<UpgradeType>().ok())
1162 .unwrap_or_default();
1163 upgrade_type
1164 }
1165
1166 /// Checks whether the WebSocket upgrade is enabled for this request.
1167 ///
1168 /// This method determines if the `UPGRADE` header indicates a WebSocket connection.
1169 ///
1170 /// # Returns
1171 ///
1172 /// - `bool` - Whether WebSocket upgrade is enabled.
1173 #[inline(always)]
1174 pub fn is_ws(&self) -> bool {
1175 self.get_upgrade_type().is_ws()
1176 }
1177
1178 /// Checks if the current upgrade type is HTTP/2 cleartext (h2c).
1179 ///
1180 /// # Returns
1181 ///
1182 /// - `bool` - Whether the upgrade type is h2c.
1183 #[inline(always)]
1184 pub fn is_h2c(&self) -> bool {
1185 self.get_upgrade_type().is_h2c()
1186 }
1187
1188 /// Checks if the current upgrade type is TLS (any version).
1189 ///
1190 /// # Returns
1191 ///
1192 /// - `bool` - Whether the upgrade type is TLS.
1193 #[inline(always)]
1194 pub fn is_tls(&self) -> bool {
1195 self.get_upgrade_type().is_tls()
1196 }
1197
1198 /// Checks whether the upgrade type is unknown.
1199 ///
1200 /// # Returns
1201 ///
1202 /// - `bool` - Whether the upgrade type is unknown.
1203 #[inline(always)]
1204 pub fn is_unknown_upgrade(&self) -> bool {
1205 self.get_upgrade_type().is_unknown()
1206 }
1207
1208 /// Checks if the HTTP version is HTTP/1.1 or higher.
1209 ///
1210 /// # Returns
1211 ///
1212 /// - `bool` - Whether the version is HTTP/1.1 or higher.
1213 #[inline(always)]
1214 pub fn is_http1_1_or_higher(&self) -> bool {
1215 self.get_version().is_http1_1_or_higher()
1216 }
1217
1218 /// Checks whether the HTTP version is HTTP/0.9.
1219 ///
1220 /// # Returns
1221 ///
1222 /// - `bool` - Whether the version is HTTP/0.9.
1223 #[inline(always)]
1224 pub fn is_http0_9(&self) -> bool {
1225 self.get_version().is_http0_9()
1226 }
1227
1228 /// Checks whether the HTTP version is HTTP/1.0.
1229 ///
1230 /// # Returns
1231 ///
1232 /// - `bool` - Whether the version is HTTP/1.0.
1233 #[inline(always)]
1234 pub fn is_http1_0(&self) -> bool {
1235 self.get_version().is_http1_0()
1236 }
1237
1238 /// Checks whether the HTTP version is HTTP/1.1.
1239 ///
1240 /// # Returns
1241 ///
1242 /// - `bool` - Whether the version is HTTP/1.1.
1243 #[inline(always)]
1244 pub fn is_http1_1(&self) -> bool {
1245 self.get_version().is_http1_1()
1246 }
1247
1248 /// Checks whether the HTTP version is HTTP/2.
1249 ///
1250 /// # Returns
1251 ///
1252 /// - `bool` - Whether the version is HTTP/2.
1253 #[inline(always)]
1254 pub fn is_http2(&self) -> bool {
1255 self.get_version().is_http2()
1256 }
1257
1258 /// Checks whether the HTTP version is HTTP/3.
1259 ///
1260 /// # Returns
1261 ///
1262 /// - `bool` - Whether the version is HTTP/3.
1263 #[inline(always)]
1264 pub fn is_http3(&self) -> bool {
1265 self.get_version().is_http3()
1266 }
1267
1268 /// Checks whether the HTTP version is unknown.
1269 ///
1270 /// # Returns
1271 ///
1272 /// - `bool` - Whether the version is unknown.
1273 #[inline(always)]
1274 pub fn is_unknown_version(&self) -> bool {
1275 self.get_version().is_unknown()
1276 }
1277
1278 /// Checks whether the version belongs to the HTTP family.
1279 ///
1280 /// # Returns
1281 ///
1282 /// - `bool` - Whether the version is HTTP.
1283 #[inline(always)]
1284 pub fn is_http(&self) -> bool {
1285 self.get_version().is_http()
1286 }
1287
1288 /// Checks whether the request method is GET.
1289 ///
1290 /// # Returns
1291 ///
1292 /// - `bool` - Whether the method is GET.
1293 #[inline(always)]
1294 pub fn is_get(&self) -> bool {
1295 self.get_method().is_get()
1296 }
1297
1298 /// Checks whether the request method is POST.
1299 ///
1300 /// # Returns
1301 ///
1302 /// - `bool` - Whether the method is POST.
1303 #[inline(always)]
1304 pub fn is_post(&self) -> bool {
1305 self.get_method().is_post()
1306 }
1307
1308 /// Checks whether the request method is PUT.
1309 ///
1310 /// # Returns
1311 ///
1312 /// - `bool` - Whether the method is PUT.
1313 #[inline(always)]
1314 pub fn is_put(&self) -> bool {
1315 self.get_method().is_put()
1316 }
1317
1318 /// Checks whether the request method is DELETE.
1319 ///
1320 /// # Returns
1321 ///
1322 /// - `bool` - Whether the method is DELETE.
1323 #[inline(always)]
1324 pub fn is_delete(&self) -> bool {
1325 self.get_method().is_delete()
1326 }
1327
1328 /// Checks whether the request method is PATCH.
1329 ///
1330 /// # Returns
1331 ///
1332 /// - `bool` - Whether the method is PATCH.
1333 #[inline(always)]
1334 pub fn is_patch(&self) -> bool {
1335 self.get_method().is_patch()
1336 }
1337
1338 /// Checks whether the request method is HEAD.
1339 ///
1340 /// # Returns
1341 ///
1342 /// - `bool` - Whether the method is HEAD.
1343 #[inline(always)]
1344 pub fn is_head(&self) -> bool {
1345 self.get_method().is_head()
1346 }
1347
1348 /// Checks whether the request method is OPTIONS.
1349 ///
1350 /// # Returns
1351 ///
1352 /// - `bool` - Whether the method is OPTIONS.
1353 #[inline(always)]
1354 pub fn is_options(&self) -> bool {
1355 self.get_method().is_options()
1356 }
1357
1358 /// Checks whether the request method is CONNECT.
1359 ///
1360 /// # Returns
1361 ///
1362 /// - `bool` - Whether the method is CONNECT.
1363 #[inline(always)]
1364 pub fn is_connect(&self) -> bool {
1365 self.get_method().is_connect()
1366 }
1367
1368 /// Checks whether the request method is TRACE.
1369 ///
1370 /// # Returns
1371 ///
1372 /// - `bool` - Whether the method is TRACE.
1373 #[inline(always)]
1374 pub fn is_trace(&self) -> bool {
1375 self.get_method().is_trace()
1376 }
1377
1378 /// Checks whether the request method is UNKNOWN.
1379 ///
1380 /// # Returns
1381 ///
1382 /// - `bool` - Whether the method is UNKNOWN.
1383 #[inline(always)]
1384 pub fn is_unknown_method(&self) -> bool {
1385 self.get_method().is_unknown()
1386 }
1387
1388 /// Determines if a keep-alive connection should be enabled for this request.
1389 ///
1390 /// This function checks the `Connection` header and the HTTP version to determine
1391 /// if keep-alive should be enabled. The logic is as follows:
1392 ///
1393 /// 1. If the `Connection` header exists:
1394 /// - Returns `true` if the header value is "keep-alive" (case-insensitive).
1395 /// - Returns `false` if the header value is "close" (case-insensitive).
1396 /// 2. If no `Connection` header is present:
1397 /// - Returns `true` if the HTTP version is 1.1 or higher.
1398 /// - Returns `false` otherwise.
1399 ///
1400 /// # Returns
1401 ///
1402 /// - `bool` - Whether keep-alive should be enabled.
1403 #[inline(always)]
1404 pub fn is_enable_keep_alive(&self) -> bool {
1405 if let Some(connection_value) = self.try_get_header_back(CONNECTION) {
1406 if connection_value.eq_ignore_ascii_case(KEEP_ALIVE) {
1407 return true;
1408 } else if connection_value.eq_ignore_ascii_case(CLOSE) {
1409 return self.is_ws();
1410 }
1411 }
1412 self.is_http1_1_or_higher() || self.is_ws()
1413 }
1414
1415 /// Determines if keep-alive should be disabled for this request.
1416 ///
1417 /// # Returns
1418 ///
1419 /// - `bool` - Whether keep-alive should be disabled.
1420 #[inline(always)]
1421 pub fn is_disable_keep_alive(&self) -> bool {
1422 !self.is_enable_keep_alive()
1423 }
1424}