Skip to main content

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
17/// Converts an I/O error to a `RequestError`.
18///
19/// Maps connection reset and aborted errors to `ClientDisconnected`,
20/// all other I/O errors are mapped to `ReadConnection`.
21impl From<std::io::Error> for RequestError {
22    /// Converts an I/O error to a `RequestError`.
23    ///
24    /// # Arguments
25    ///
26    /// - `std::io::Error`: The I/O error to convert.
27    ///
28    /// # Returns
29    ///
30    /// - `RequestError`: The corresponding request error.
31    #[inline(always)]
32    fn from(error: std::io::Error) -> Self {
33        let kind: ErrorKind = error.kind();
34        if kind == ErrorKind::ConnectionReset || kind == ErrorKind::ConnectionAborted {
35            return RequestError::ClientDisconnected(HttpStatus::BadRequest);
36        }
37        RequestError::ReadConnection(HttpStatus::BadRequest)
38    }
39}
40
41/// Converts a timeout elapsed error to a `RequestError`.
42///
43/// Maps timeout errors to `ReadTimeout` with `HttpStatus::RequestTimeout`.
44impl From<Elapsed> for RequestError {
45    /// Converts a timeout elapsed error to a `RequestError`.
46    ///
47    /// # Arguments
48    ///
49    /// - `Elapsed`: The elapsed error to convert.
50    ///
51    /// # Returns
52    ///
53    /// - `RequestError`: The corresponding request error as `ReadTimeout`.
54    #[inline(always)]
55    fn from(_: Elapsed) -> Self {
56        RequestError::ReadTimeout(HttpStatus::RequestTimeout)
57    }
58}
59
60/// Converts a parse int error to a `RequestError`.
61///
62/// Maps parse int errors to `InvalidContentLength` with `HttpStatus::BadRequest`.
63impl From<ParseIntError> for RequestError {
64    /// Converts a parse int error to a `RequestError`.
65    ///
66    /// # Arguments
67    ///
68    /// - `ParseIntError`: The parse error to convert.
69    ///
70    /// # Returns
71    ///
72    /// - `RequestError`: The corresponding request error as `InvalidContentLength`.
73    #[inline(always)]
74    fn from(_: ParseIntError) -> Self {
75        RequestError::InvalidContentLength(HttpStatus::BadRequest)
76    }
77}
78
79/// Converts a response error to a `RequestError`.
80///
81/// Maps response errors to `WriteTimeout` with `HttpStatus::InternalServerError`.
82impl From<ResponseError> for RequestError {
83    /// Converts a response error to a `RequestError`.
84    ///
85    /// # Arguments
86    ///
87    /// - `ResponseError`: The response error to convert.
88    ///
89    /// # Returns
90    ///
91    /// - `RequestError`: The corresponding request error as `WriteTimeout`.
92    #[inline(always)]
93    fn from(_: ResponseError) -> Self {
94        RequestError::WriteTimeout(HttpStatus::InternalServerError)
95    }
96}
97
98impl RequestError {
99    /// Gets the HTTP status associated with this error.
100    ///
101    /// Returns the HttpStatus enum variant that corresponds to this error.
102    ///
103    /// # Returns
104    ///
105    /// - `HttpStatus` - The HTTP status associated with this error.
106    pub fn get_http_status(&self) -> HttpStatus {
107        match self {
108            Self::HttpRead(status) => *status,
109            Self::GetTcpStream(status) => *status,
110            Self::GetTlsStream(status) => *status,
111            Self::ReadConnection(status) => *status,
112            Self::RequestAborted(status) => *status,
113            Self::TlsStreamConnect(status) => *status,
114            Self::NeedOpenRedirect(status) => *status,
115            Self::MaxRedirectTimes(status) => *status,
116            Self::MethodsNotSupport(status) => *status,
117            Self::RedirectInvalidUrl(status) => *status,
118            Self::ClientDisconnected(status) => *status,
119            Self::RedirectUrlDeadLoop(status) => *status,
120            Self::ClientClosedConnection(status) => *status,
121            Self::IncompleteWebSocketFrame(status) => *status,
122            Self::RequestTooLong(status) => *status,
123            Self::PathTooLong(status) => *status,
124            Self::QueryTooLong(status) => *status,
125            Self::HeaderLineTooLong(status) => *status,
126            Self::TooManyHeaders(status) => *status,
127            Self::HeaderKeyTooLong(status) => *status,
128            Self::HeaderValueTooLong(status) => *status,
129            Self::ContentLengthTooLarge(status) => *status,
130            Self::InvalidContentLength(status) => *status,
131            Self::InvalidUrlScheme(status) => *status,
132            Self::InvalidUrlHost(status) => *status,
133            Self::InvalidUrlPort(status) => *status,
134            Self::InvalidUrlPath(status) => *status,
135            Self::InvalidUrlQuery(status) => *status,
136            Self::InvalidUrlFragment(status) => *status,
137            Self::ReadTimeout(status) => *status,
138            Self::WriteTimeout(status) => *status,
139            Self::TcpConnectionFailed(status) => *status,
140            Self::TlsHandshakeFailed(status) => *status,
141            Self::TlsCertificateInvalid(status) => *status,
142            Self::WebSocketFrameTooLarge(status) => *status,
143            Self::WebSocketOpcodeUnsupported(status) => *status,
144            Self::WebSocketMaskMissing(status) => *status,
145            Self::WebSocketPayloadCorrupted(status) => *status,
146            Self::WebSocketInvalidUtf8(status) => *status,
147            Self::WebSocketInvalidCloseCode(status) => *status,
148            Self::WebSocketInvalidExtension(status) => *status,
149            Self::HttpRequestPartsInsufficient(status) => *status,
150            Self::TcpStreamConnect(status) => *status,
151            Self::TlsConnectorBuild(status) => *status,
152            Self::InvalidUrl(status) => *status,
153            Self::ConfigReadError(status) => *status,
154            Self::TcpStreamConnectString(status) => *status,
155            Self::TlsConnectorBuildString(status) => *status,
156            Self::Request(_) => HttpStatus::BadRequest,
157            Self::Unknown(status) => *status,
158        }
159    }
160
161    /// Gets the numeric HTTP status code associated with this error.
162    ///
163    /// Returns the numeric status code (e.g., 400, 404, 500) that corresponds to this error.
164    ///
165    /// # Returns
166    ///
167    /// - `ResponseStatusCode` - The numeric HTTP status code.
168    pub fn get_http_status_code(&self) -> ResponseStatusCode {
169        self.get_http_status().code()
170    }
171}
172
173/// Implementation of `Default` trait for `RequestConfig`.
174impl Default for RequestConfig {
175    /// Creates a new `RequestConfig` with default secure settings.
176    ///
177    /// This constructor initializes the configuration with standard security limits
178    /// suitable for most HTTP request parsing scenarios.
179    ///
180    /// # Returns
181    ///
182    /// - `Self` - A new `RequestConfig` instance with default settings.
183    #[inline(always)]
184    fn default() -> Self {
185        Self {
186            buffer_size: DEFAULT_BUFFER_SIZE,
187            max_path_size: DEFAULT_MAX_PATH_SIZE,
188            max_header_count: DEFAULT_MAX_HEADER_COUNT,
189            max_header_key_size: DEFAULT_MAX_HEADER_KEY_SIZE,
190            max_header_value_size: DEFAULT_MAX_HEADER_VALUE_SIZE,
191            max_body_size: DEFAULT_MAX_BODY_SIZE,
192            read_timeout_ms: DEFAULT_READ_TIMEOUT_MS,
193        }
194    }
195}
196
197impl RequestConfig {
198    /// Creates a new `RequestConfig` from a JSON string.
199    ///
200    /// # Arguments
201    ///
202    /// - `AsRef<str>` - The configuration.
203    ///
204    /// # Returns
205    ///
206    /// - `Result<RequestConfig, serde_json::Error>` - The parsed `RequestConfig` or an error.
207    pub fn from_json<C>(json: C) -> Result<RequestConfig, serde_json::Error>
208    where
209        C: AsRef<str>,
210    {
211        serde_json::from_str(json.as_ref())
212    }
213
214    /// Creates a new `RequestConfig` with low-security settings.
215    ///
216    /// This constructor initializes the configuration with less restrictive limits
217    /// for environments where higher limits are needed.
218    ///
219    /// # Returns
220    ///
221    /// - `Self` - A new `RequestConfig` instance with low-security settings.
222    #[inline(always)]
223    pub fn low_security() -> Self {
224        Self {
225            buffer_size: DEFAULT_LOW_SECURITY_BUFFER_SIZE,
226            max_path_size: DEFAULT_LOW_SECURITY_MAX_PATH_SIZE,
227            max_header_count: DEFAULT_LOW_SECURITY_MAX_HEADER_COUNT,
228            max_header_key_size: DEFAULT_LOW_SECURITY_MAX_HEADER_KEY_SIZE,
229            max_header_value_size: DEFAULT_LOW_SECURITY_MAX_HEADER_VALUE_SIZE,
230            max_body_size: DEFAULT_LOW_SECURITY_MAX_BODY_SIZE,
231            read_timeout_ms: DEFAULT_LOW_SECURITY_READ_TIMEOUT_MS,
232        }
233    }
234
235    /// Creates a new `RequestConfig` with high-security settings.
236    ///
237    /// This constructor initializes the configuration with more restrictive limits
238    /// to provide maximum protection against various attacks in high-risk environments.
239    ///
240    /// # Returns
241    ///
242    /// - `Self` - A new `RequestConfig` instance with high-security settings.
243    #[inline(always)]
244    pub fn high_security() -> Self {
245        Self {
246            buffer_size: DEFAULT_HIGH_SECURITY_BUFFER_SIZE,
247            max_path_size: DEFAULT_HIGH_SECURITY_MAX_PATH_SIZE,
248            max_header_count: DEFAULT_HIGH_SECURITY_MAX_HEADER_COUNT,
249            max_header_key_size: DEFAULT_HIGH_SECURITY_MAX_HEADER_KEY_SIZE,
250            max_header_value_size: DEFAULT_HIGH_SECURITY_MAX_HEADER_VALUE_SIZE,
251            max_body_size: DEFAULT_HIGH_SECURITY_MAX_BODY_SIZE,
252            read_timeout_ms: DEFAULT_HIGH_SECURITY_READ_TIMEOUT_MS,
253        }
254    }
255}
256
257/// Provides a default value for `Request`.
258///
259/// Returns a new `Request` instance with all fields initialized to their default values.
260impl Default for Request {
261    #[inline(always)]
262    fn default() -> Self {
263        Self {
264            method: Method::default(),
265            host: String::new(),
266            version: HttpVersion::default(),
267            path: String::new(),
268            querys: hash_map_xx_hash3_64(),
269            headers: hash_map_xx_hash3_64(),
270            body: Vec::new(),
271        }
272    }
273}
274
275impl Http {
276    /// Parses the first line of HTTP request into method, path, and version components.
277    ///
278    /// # Arguments
279    ///
280    /// - `&str`: The first line string of HTTP request to parse.
281    ///
282    /// # Returns
283    ///
284    /// - `Result<(RequestMethod, &str, RequestVersion), RequestError>`: A tuple containing:
285    ///   - The parsed HTTP method
286    ///   - The full path string
287    ///   - The parsed HTTP version
288    ///   - Or an error if parsing fails
289    #[inline(always)]
290    fn parse_first_line(line: &str) -> Result<(RequestMethod, &str, RequestVersion), RequestError> {
291        let mut parts: SplitWhitespace<'_> = line.split_whitespace();
292        let method_str: &str = parts
293            .next()
294            .ok_or(RequestError::HttpRequestPartsInsufficient(
295                HttpStatus::BadRequest,
296            ))?;
297        let full_path: &str = parts
298            .next()
299            .ok_or(RequestError::HttpRequestPartsInsufficient(
300                HttpStatus::BadRequest,
301            ))?;
302        let version_str: &str = parts
303            .next()
304            .ok_or(RequestError::HttpRequestPartsInsufficient(
305                HttpStatus::BadRequest,
306            ))?;
307        let method: RequestMethod = method_str
308            .parse::<RequestMethod>()
309            .unwrap_or_else(|_| Method::Unknown(method_str.to_string()));
310        let version: RequestVersion = version_str
311            .parse::<RequestVersion>()
312            .unwrap_or_else(|_| RequestVersion::Unknown(version_str.to_string()));
313        Ok((method, full_path, version))
314    }
315
316    /// Validates the path length against the maximum allowed size.
317    ///
318    /// # Arguments
319    ///
320    /// - `&str`: The path string to check.
321    /// - `usize`: The maximum allowed path size.
322    ///
323    /// # Returns
324    ///
325    /// - `Result<(), RequestError>`: Ok if valid, or an error if the path is too long.
326    #[inline(always)]
327    fn check_path_size(path: &str, max_size: usize) -> Result<(), RequestError> {
328        if path.len() > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_PATH_SIZE {
329            return Err(RequestError::PathTooLong(HttpStatus::URITooLong));
330        }
331        Ok(())
332    }
333
334    /// Parses the query string from the full path.
335    ///
336    /// Handles both query parameters (after `?`) and hash fragments (after `#`),
337    /// ensuring proper parsing when both are present.
338    ///
339    /// # Arguments
340    ///
341    /// - `&str`: The full path string containing the query.
342    /// - `Option<usize>`: The index of the query separator (`?`), if present.
343    /// - `Option<usize>`: The index of the hash separator (`#`), if present.
344    ///
345    /// # Returns
346    ///
347    /// - `&str`: The parsed query string slice, or empty string if no query.
348    #[inline(always)]
349    fn get_query_slice<'a>(
350        path: &'a str,
351        query_index: Option<usize>,
352        hash_index: Option<usize>,
353    ) -> &'a str {
354        query_index.map_or(EMPTY_STR, |i: usize| {
355            let temp: &'a str = &path[i + 1..];
356            match hash_index {
357                None => temp,
358                Some(hash_idx) if hash_idx <= i => temp,
359                Some(hash_idx) => &temp[..hash_idx - i - 1],
360            }
361        })
362    }
363
364    /// Parses the request path without query string or hash fragment.
365    ///
366    /// # Arguments
367    ///
368    /// - `&str`: The full path string.
369    /// - `Option<usize>`: The index of the query separator (`?`), if present.
370    /// - `Option<usize>`: The index of the hash separator (`#`), if present.
371    ///
372    /// # Returns
373    ///
374    /// - `RequestPath`: The request path without query or hash.
375    #[inline(always)]
376    fn parse_path(
377        path: &str,
378        query_index: Option<usize>,
379        hash_index: Option<usize>,
380    ) -> RequestPath {
381        match query_index.or(hash_index) {
382            Some(i) => path[..i].to_owned(),
383            None => path.to_owned(),
384        }
385    }
386
387    /// Parses a query string as_ref key-value pairs.
388    ///
389    /// Expects format "key1=value1&key2=value2". Empty values are allowed.
390    ///
391    /// # Arguments
392    ///
393    /// - `&str` - The query string to parse.
394    ///
395    /// # Returns
396    ///
397    /// - `RequestQuerys` - The parsed query parameters.
398    #[inline(always)]
399    fn parse_querys(query: &str) -> RequestQuerys {
400        let estimated_capacity: usize = query.matches(AND).count() + 1;
401        let mut query_map: RequestQuerys = HashMapXxHash3_64::with_capacity_and_hasher(
402            estimated_capacity,
403            BuildHasherDefault::default(),
404        );
405        for pair in query.split(AND) {
406            if let Some((key, value)) = pair.split_once(EQUAL) {
407                if !key.is_empty() {
408                    query_map.insert(key.to_string(), value.to_string());
409                }
410            } else if !pair.is_empty() {
411                query_map.insert(pair.to_string(), String::new());
412            }
413        }
414        query_map
415    }
416
417    /// Checks if the header count exceeds the maximum allowed.
418    ///
419    /// # Arguments
420    ///
421    /// - `usize`: The current number of headers parsed.
422    /// - `usize`: The maximum allowed number of headers.
423    ///
424    /// # Returns
425    ///
426    /// - `Result<(), RequestError>`: Returns an error if the limit is exceeded and not in low security mode.
427    #[inline(always)]
428    fn check_header_count(count: usize, max_count: usize) -> Result<(), RequestError> {
429        if count > max_count && max_count != DEFAULT_LOW_SECURITY_MAX_HEADER_COUNT {
430            return Err(RequestError::TooManyHeaders(
431                HttpStatus::RequestHeaderFieldsTooLarge,
432            ));
433        }
434        Ok(())
435    }
436
437    /// Checks if a header key exceeds the maximum allowed length.
438    ///
439    /// # Arguments
440    ///
441    /// - `&str`: The header key to check.
442    /// - `usize`: The maximum allowed length for a header key.
443    ///
444    /// # Returns
445    ///
446    /// - `Result<(), RequestError>`: Returns an error if the limit is exceeded and not in low security mode.
447    #[inline(always)]
448    fn check_header_key_size(key: &str, max_size: usize) -> Result<(), RequestError> {
449        if key.len() > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_HEADER_KEY_SIZE {
450            return Err(RequestError::HeaderKeyTooLong(
451                HttpStatus::RequestHeaderFieldsTooLarge,
452            ));
453        }
454        Ok(())
455    }
456
457    /// Checks if a header value exceeds the maximum allowed length.
458    ///
459    /// # Arguments
460    ///
461    /// - `&str`: The header value to check.
462    /// - `usize`: The maximum allowed length for a header value.
463    ///
464    /// # Returns
465    ///
466    /// - `Result<(), RequestError>`: Returns an error if the limit is exceeded and not in low security mode.
467    #[inline(always)]
468    fn check_header_value_size(value: &str, max_size: usize) -> Result<(), RequestError> {
469        if value.len() > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_HEADER_VALUE_SIZE {
470            return Err(RequestError::HeaderValueTooLong(
471                HttpStatus::RequestHeaderFieldsTooLarge,
472            ));
473        }
474        Ok(())
475    }
476
477    /// Parses the Content-Length header value and checks it against max body size.
478    ///
479    /// # Arguments
480    ///
481    /// - `&str`: The Content-Length header value string.
482    /// - `usize`: The maximum allowed body size.
483    ///
484    /// # Returns
485    ///
486    /// - `Result<usize, RequestError>`: The parsed content length or an error.
487    #[inline(always)]
488    fn check_body_size(value: &str, max_size: usize) -> Result<usize, RequestError> {
489        let length: usize = value.parse::<usize>()?;
490        if length > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_BODY_SIZE {
491            return Err(RequestError::ContentLengthTooLarge(
492                HttpStatus::PayloadTooLarge,
493            ));
494        }
495        Ok(length)
496    }
497
498    /// Parses HTTP headers from a buffered reader.
499    ///
500    /// This method reads header lines from the provided buffered reader until an empty line
501    /// is encountered, which indicates the end of headers. It checks header count, length,
502    /// and content according to the provided configuration.
503    ///
504    /// # Arguments
505    ///
506    /// - `&mut AsyncBufReadExt + Unpin`: A mutable reference to a buffered reader implementing `AsyncBufReadExt`.
507    /// - `&RequestConfig`: Configuration for security limits and buffer settings.
508    ///
509    /// # Returns
510    ///
511    /// - `Result<(RequestHeaders, RequestHost, usize), RequestError>`: A tuple containing:
512    ///   - The parsed headers as a hash map
513    ///   - The host value parsed from the Host header
514    ///   - The content length parsed from the Content-Length header
515    ///   - Or an error if parsing fails
516    async fn parse_headers<R>(
517        reader: &mut R,
518        config: &RequestConfig,
519    ) -> Result<(RequestHeaders, RequestHost, usize), RequestError>
520    where
521        R: AsyncBufReadExt + Unpin,
522    {
523        let buffer_size: usize = config.get_buffer_size();
524        let max_header_count: usize = config.get_max_header_count();
525        let max_header_key_size: usize = config.get_max_header_key_size();
526        let max_header_value_size: usize = config.get_max_header_value_size();
527        let max_body_size: usize = config.get_max_body_size();
528        let mut headers: RequestHeaders =
529            HashMapXxHash3_64::with_capacity_and_hasher(B_16, BuildHasherDefault::default());
530        let mut host: RequestHost = String::new();
531        let mut content_size: usize = 0;
532        let mut header_count: usize = 0;
533        let mut header_line_buffer: String = String::with_capacity(buffer_size);
534        loop {
535            header_line_buffer.clear();
536            AsyncBufReadExt::read_line(reader, &mut header_line_buffer).await?;
537            let header_line: &str = header_line_buffer.trim();
538            if header_line.is_empty() {
539                break;
540            }
541            header_count += 1;
542            Self::check_header_count(header_count, max_header_count)?;
543            let (key_part, value_part): (&str, &str) = match header_line.split_once(COLON) {
544                Some(parts) => parts,
545                None => continue,
546            };
547            let key_trimmed: &str = key_part.trim();
548            if key_trimmed.is_empty() {
549                continue;
550            }
551            let key: String = key_trimmed.to_ascii_lowercase();
552            Self::check_header_key_size(&key, max_header_key_size)?;
553            let value: String = value_part.trim().to_string();
554            Self::check_header_value_size(&value, max_header_value_size)?;
555            match key.as_str() {
556                HOST => host = value.clone(),
557                CONTENT_LENGTH => {
558                    content_size = Self::check_body_size(&value, max_body_size)?;
559                }
560                _ => {}
561            }
562            headers.entry(key).or_default().push_back(value);
563        }
564        Ok((headers, host, content_size))
565    }
566
567    /// Reads the request body from the buffered reader.
568    ///
569    /// # Arguments
570    ///
571    /// - `&mut BufReader<&mut TcpStream>`: The buffered reader to read from.
572    /// - `usize`: The expected content size.
573    ///
574    /// # Returns
575    ///
576    /// - `Result<RequestBody, RequestError>`: The body bytes or an error.
577    #[inline(always)]
578    async fn parse_body(
579        reader: &mut BufReader<&mut TcpStream>,
580        content_size: usize,
581    ) -> Result<RequestBody, RequestError> {
582        let mut body: RequestBody = Vec::with_capacity(content_size);
583        if content_size > 0 {
584            body.resize(content_size, 0);
585            AsyncReadExt::read_exact(reader, &mut body).await?;
586        }
587        Ok(body)
588    }
589
590    /// Parses the HTTP request content from the stream.
591    ///
592    /// This is an internal helper function that performs the actual parsing.
593    ///
594    /// # Arguments
595    ///
596    /// - `&ArcRwLock<TcpStream>`: The TCP stream to read from.
597    /// - `&RequestConfig`: Configuration for security limits and buffer settings.
598    ///
599    /// # Returns
600    ///
601    /// - `Result<Request, RequestError>`: The parsed request or an error.
602    async fn parse_from_stream(
603        stream: &ArcRwLockStream,
604        config: &RequestConfig,
605    ) -> Result<Request, RequestError> {
606        let buffer_size: usize = config.get_buffer_size();
607        let max_path_size: usize = config.get_max_path_size();
608        let mut buf_stream: RwLockWriteGuard<'_, TcpStream> = stream.write().await;
609        let reader: &mut BufReader<&mut TcpStream> =
610            &mut BufReader::with_capacity(buffer_size, &mut buf_stream);
611        let mut line: String = String::with_capacity(buffer_size);
612        AsyncBufReadExt::read_line(reader, &mut line).await?;
613        let (method, path, version): (RequestMethod, &str, RequestVersion) =
614            Self::parse_first_line(&line)?;
615        Self::check_path_size(path, max_path_size)?;
616        let hash_index: Option<usize> = path.find(HASH);
617        let query_index: Option<usize> = path.find(QUERY);
618        let query_slice: &str = Self::get_query_slice(path, query_index, hash_index);
619        let querys: RequestQuerys = Self::parse_querys(query_slice);
620        let path: RequestPath = Self::parse_path(path, query_index, hash_index);
621        let (headers, host, content_size): (RequestHeaders, RequestHost, usize) =
622            Self::parse_headers(reader, config).await?;
623        let body: RequestBody = Self::parse_body(reader, content_size).await?;
624        Ok(Request {
625            method,
626            host,
627            version,
628            path,
629            querys,
630            headers,
631            body,
632        })
633    }
634}
635
636impl Ws {
637    /// Reads data from the stream with optional timeout handling.
638    ///
639    /// # Arguments
640    ///
641    /// - `&ArcRwLockStream`: The TCP stream to read from.
642    /// - `&mut [u8]`: The buffer to read data into.
643    /// - `Option<Duration>`: The optional timeout duration. If Some, timeout is applied; if None, no timeout.
644    /// - `&mut bool`: Mutable reference to track if we got a client response.
645    ///
646    /// # Returns
647    ///
648    /// - `Result<Option<usize>, RequestError>`: The number of bytes read, None for timeout/ping, or an error.
649    async fn read(
650        stream: &ArcRwLockStream,
651        buffer: &mut [u8],
652        duration_opt: Option<Duration>,
653        is_client_response: &mut bool,
654    ) -> Result<Option<usize>, RequestError> {
655        if let Some(duration) = duration_opt {
656            return match timeout(duration, stream.write().await.read(buffer)).await {
657                Ok(result) => match result {
658                    Ok(len) => Ok(Some(len)),
659                    Err(error) => Err(error.into()),
660                },
661                Err(error) => {
662                    if !*is_client_response {
663                        return Err(error.into());
664                    }
665                    *is_client_response = false;
666                    stream.try_send_body(&PING_FRAME).await?;
667                    Ok(None)
668                }
669            };
670        }
671        match stream.write().await.read(buffer).await {
672            Ok(len) => Ok(Some(len)),
673            Err(error) => Err(error.into()),
674        }
675    }
676
677    /// Handles a decoded WebSocket Text or Binary frame and accumulates payload data.
678    ///
679    /// # Arguments
680    ///
681    /// - `&Request`: The request to update on completion.
682    /// - `&WebSocketFrame`: The decoded WebSocket frame.
683    /// - `&mut Vec<u8>`: The accumulated frame data.
684    ///
685    /// # Returns
686    ///
687    /// - `Result<Option<Request>, RequestError>`: Some(request) if frame is complete, None to continue, or error.
688    #[inline(always)]
689    fn parse_frame(
690        request: &Request,
691        frame: &WebSocketFrame,
692        full_frame: &mut Vec<u8>,
693    ) -> Result<Option<Request>, RequestError> {
694        let payload_data: &[u8] = frame.get_payload_data();
695        full_frame.extend_from_slice(payload_data);
696        if *frame.get_fin() {
697            let mut result: Request = request.clone();
698            result.body = full_frame.clone();
699            return Ok(Some(result));
700        }
701        Ok(None)
702    }
703}
704
705impl Request {
706    /// Parses an HTTP request from a TCP stream.
707    ///
708    /// Wraps the stream in a buffered reader and delegates to `http_from_reader`.
709    /// If the timeout is DEFAULT_LOW_SECURITY_READ_TIMEOUT_MS, no timeout is applied.
710    ///
711    /// # Arguments
712    ///
713    /// - `&ArcRwLock<TcpStream>` - The TCP stream to read from.
714    /// - `&RequestConfig` - Configuration for security limits and buffer settings.
715    ///
716    /// # Returns
717    ///
718    /// - `Result<Request, RequestError>` - The parsed request or an error.
719    pub async fn http_from_stream(
720        stream: &ArcRwLockStream,
721        config: &RequestConfig,
722    ) -> Result<Request, RequestError> {
723        let timeout_ms: u64 = config.get_read_timeout_ms();
724        if timeout_ms == DEFAULT_LOW_SECURITY_READ_TIMEOUT_MS {
725            return Http::parse_from_stream(stream, config).await;
726        }
727        let duration: Duration = Duration::from_millis(timeout_ms);
728        timeout(duration, Http::parse_from_stream(stream, config)).await?
729    }
730
731    /// Parses a WebSocket request from a TCP stream.
732    ///
733    /// Wraps the stream in a buffered reader and delegates to `ws_from_reader`.
734    /// If the timeout is DEFAULT_LOW_SECURITY_READ_TIMEOUT_MS, no timeout is applied.
735    ///
736    /// # Arguments
737    ///
738    /// - `&ArcRwLock<TcpStream>`: The TCP stream to read from.
739    /// - `&RequestConfig`: Configuration for security limits and buffer settings.
740    ///
741    /// # Returns
742    ///
743    /// - `Result<Request, RequestError>`: The parsed WebSocket request or an error.
744    pub async fn ws_from_stream(
745        &self,
746        stream: &ArcRwLockStream,
747        config: &RequestConfig,
748    ) -> Result<Request, RequestError> {
749        let buffer_size: usize = config.get_buffer_size();
750        let read_timeout_ms: u64 = config.get_read_timeout_ms();
751        let mut dynamic_buffer: Vec<u8> = Vec::with_capacity(buffer_size);
752        let mut temp_buffer: Vec<u8> = vec![0; buffer_size];
753        let mut full_frame: Vec<u8> = Vec::new();
754        let mut is_client_response: bool = false;
755        let duration_opt: Option<Duration> =
756            if read_timeout_ms == DEFAULT_LOW_SECURITY_READ_TIMEOUT_MS {
757                None
758            } else {
759                let adjusted_timeout_ms: u64 = (read_timeout_ms >> 1) + (read_timeout_ms & 1);
760                Some(Duration::from_millis(adjusted_timeout_ms))
761            };
762        loop {
763            let len: usize = match Ws::read(
764                stream,
765                &mut temp_buffer,
766                duration_opt,
767                &mut is_client_response,
768            )
769            .await
770            {
771                Ok(Some(len)) => len,
772                Ok(None) => continue,
773                Err(error) => return Err(error),
774            };
775            if len == 0 {
776                return Err(RequestError::IncompleteWebSocketFrame(
777                    HttpStatus::BadRequest,
778                ));
779            }
780            dynamic_buffer.extend_from_slice(&temp_buffer[..len]);
781            while let Some((frame, consumed)) = WebSocketFrame::decode_ws_frame(&dynamic_buffer) {
782                is_client_response = true;
783                dynamic_buffer.drain(0..consumed);
784                match frame.get_opcode() {
785                    WebSocketOpcode::Close => {
786                        return Err(RequestError::ClientClosedConnection(HttpStatus::BadRequest));
787                    }
788                    WebSocketOpcode::Ping | WebSocketOpcode::Pong => continue,
789                    WebSocketOpcode::Text | WebSocketOpcode::Binary => {
790                        match Ws::parse_frame(self, &frame, &mut full_frame) {
791                            Ok(Some(result)) => return Ok(result),
792                            Ok(None) => continue,
793                            Err(error) => return Err(error),
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_size<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_size<K>(&self, key: K) -> usize
998    where
999        K: AsRef<str>,
1000    {
1001        self.try_get_header_size(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_size(&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_size(&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.iter().any(|v| v == value.as_ref())
1059        } else {
1060            false
1061        }
1062    }
1063
1064    /// Tries to parse cookies from the `Cookie` header.
1065    ///
1066    /// This method retrieves the `Cookie` header value and parses it into
1067    /// a collection of key-value pairs representing the cookies.
1068    ///
1069    /// # Returns
1070    ///
1071    /// - `Option<Cookies>` - The parsed cookies if the header exists, otherwise `None`.
1072    #[inline(always)]
1073    pub fn try_get_cookies(&self) -> Option<Cookies> {
1074        self.try_get_header_back(COOKIE)
1075            .map(|cookie_header: String| Cookie::parse(cookie_header))
1076    }
1077
1078    /// Parses cookies from the `Cookie` header.
1079    ///
1080    /// This method retrieves the `Cookie` header value and parses it into
1081    /// a collection of key-value pairs representing the cookies.
1082    ///
1083    /// # Returns
1084    ///
1085    /// - `Cookies` - The parsed cookies.
1086    ///
1087    /// # Panics
1088    ///
1089    /// This function will panic if the `Cookie` header is not found.
1090    #[inline(always)]
1091    pub fn get_cookies(&self) -> Cookies {
1092        self.try_get_cookies().unwrap()
1093    }
1094
1095    /// Tries to get a cookie value by its key.
1096    ///
1097    /// This method first parses the cookies from the `Cookie` header,
1098    /// then attempts to retrieve the value for the specified key.
1099    ///
1100    /// # Arguments
1101    ///
1102    /// - `AsRef<str>` - The cookie key (implements AsRef<str>).
1103    ///
1104    /// # Returns
1105    ///
1106    /// - `Option<CookieValue>` - The cookie value if exists.
1107    #[inline(always)]
1108    pub fn try_get_cookie<K>(&self, key: K) -> Option<CookieValue>
1109    where
1110        K: AsRef<str>,
1111    {
1112        self.try_get_cookies()
1113            .and_then(|cookies: Cookies| cookies.get(key.as_ref()).cloned())
1114    }
1115
1116    /// Gets a cookie value by its key.
1117    ///
1118    /// This method first parses the cookies from the `Cookie` header,
1119    /// then retrieves the value for the specified key.
1120    ///
1121    /// # Arguments
1122    ///
1123    /// - `AsRef<str>` - The cookie key (implements AsRef<str>).
1124    ///
1125    /// # Returns
1126    ///
1127    /// - `CookieValue` - The cookie value.
1128    ///
1129    /// # Panics
1130    ///
1131    /// This function will panic if the `Cookie` header is not found
1132    /// or the cookie key does not exist.
1133    #[inline(always)]
1134    pub fn get_cookie<K>(&self, key: K) -> CookieValue
1135    where
1136        K: AsRef<str>,
1137    {
1138        self.try_get_cookie(key).unwrap()
1139    }
1140
1141    /// Retrieves the upgrade type from the request headers.
1142    ///
1143    /// This method looks for the `UPGRADE` header and attempts to parse its value
1144    /// as_ref an `UpgradeType`. If the header is missing or the value is invalid,
1145    /// it returns the default `UpgradeType`.
1146    ///
1147    /// # Returns
1148    ///
1149    /// - `UpgradeType` - The parsed upgrade type.
1150    #[inline(always)]
1151    pub fn get_upgrade_type(&self) -> UpgradeType {
1152        self.try_get_header_back(UPGRADE)
1153            .and_then(|data| data.parse::<UpgradeType>().ok())
1154            .unwrap_or_default()
1155    }
1156
1157    /// Retrieves the body content of the request as a UTF-8 encoded string.
1158    ///
1159    /// This method uses `String::from_utf8_lossy` to convert the byte slice returned by `self.get_body()` as a string.
1160    /// If the byte slice contains invalid UTF-8 sequences, they will be replaced with the Unicode replacement character ().
1161    ///
1162    /// # Returns
1163    ///
1164    /// - `String` - The body content as a string.
1165    #[inline(always)]
1166    pub fn get_body_string(&self) -> String {
1167        String::from_utf8_lossy(self.get_body()).into_owned()
1168    }
1169
1170    /// Deserializes the body content of the request as_ref a specified type `T`.
1171    ///
1172    /// This method first retrieves the body content as a byte slice using `self.get_body()`.
1173    /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
1174    ///
1175    /// # Arguments
1176    ///
1177    /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
1178    ///
1179    /// # Returns
1180    ///
1181    /// - `Result<T, serde_json::Error>` - The deserialization result.
1182    #[inline(always)]
1183    pub fn try_get_body_json<T>(&self) -> Result<T, serde_json::Error>
1184    where
1185        T: DeserializeOwned,
1186    {
1187        serde_json::from_slice(self.get_body())
1188    }
1189
1190    /// Deserializes the body content of the request as_ref a specified type `T`.
1191    ///
1192    /// This method first retrieves the body content as a byte slice using `self.get_body()`.
1193    /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
1194    ///
1195    /// # Arguments
1196    ///
1197    /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
1198    ///
1199    /// # Returns
1200    ///
1201    /// - `T` - The deserialized body content.
1202    ///
1203    /// # Panics
1204    ///
1205    /// This function will panic if the deserialization fails.
1206    #[inline(always)]
1207    pub fn get_body_json<T>(&self) -> T
1208    where
1209        T: DeserializeOwned,
1210    {
1211        self.try_get_body_json().unwrap()
1212    }
1213
1214    /// Checks whether the request method is GET.
1215    ///
1216    /// # Returns
1217    ///
1218    /// - `bool` - Whether the method is GET.
1219    #[inline(always)]
1220    pub fn is_get_method(&self) -> bool {
1221        self.get_method().is_get()
1222    }
1223
1224    /// Checks whether the request method is POST.
1225    ///
1226    /// # Returns
1227    ///
1228    /// - `bool` - Whether the method is POST.
1229    #[inline(always)]
1230    pub fn is_post_method(&self) -> bool {
1231        self.get_method().is_post()
1232    }
1233
1234    /// Checks whether the request method is PUT.
1235    ///
1236    /// # Returns
1237    ///
1238    /// - `bool` - Whether the method is PUT.
1239    #[inline(always)]
1240    pub fn is_put_method(&self) -> bool {
1241        self.get_method().is_put()
1242    }
1243
1244    /// Checks whether the request method is DELETE.
1245    ///
1246    /// # Returns
1247    ///
1248    /// - `bool` - Whether the method is DELETE.
1249    #[inline(always)]
1250    pub fn is_delete_method(&self) -> bool {
1251        self.get_method().is_delete()
1252    }
1253
1254    /// Checks whether the request method is PATCH.
1255    ///
1256    /// # Returns
1257    ///
1258    /// - `bool` - Whether the method is PATCH.
1259    #[inline(always)]
1260    pub fn is_patch_method(&self) -> bool {
1261        self.get_method().is_patch()
1262    }
1263
1264    /// Checks whether the request method is HEAD.
1265    ///
1266    /// # Returns
1267    ///
1268    /// - `bool` - Whether the method is HEAD.
1269    #[inline(always)]
1270    pub fn is_head_method(&self) -> bool {
1271        self.get_method().is_head()
1272    }
1273
1274    /// Checks whether the request method is OPTIONS.
1275    ///
1276    /// # Returns
1277    ///
1278    /// - `bool` - Whether the method is OPTIONS.
1279    #[inline(always)]
1280    pub fn is_options_method(&self) -> bool {
1281        self.get_method().is_options()
1282    }
1283
1284    /// Checks whether the request method is CONNECT.
1285    ///
1286    /// # Returns
1287    ///
1288    /// - `bool` - Whether the method is CONNECT.
1289    #[inline(always)]
1290    pub fn is_connect_method(&self) -> bool {
1291        self.get_method().is_connect()
1292    }
1293
1294    /// Checks whether the request method is TRACE.
1295    ///
1296    /// # Returns
1297    ///
1298    /// - `bool` - Whether the method is TRACE.
1299    #[inline(always)]
1300    pub fn is_trace_method(&self) -> bool {
1301        self.get_method().is_trace()
1302    }
1303
1304    /// Checks whether the request method is UNKNOWN.
1305    ///
1306    /// # Returns
1307    ///
1308    /// - `bool` - Whether the method is UNKNOWN.
1309    #[inline(always)]
1310    pub fn is_unknown_method(&self) -> bool {
1311        self.get_method().is_unknown()
1312    }
1313
1314    /// Checks whether the HTTP version is HTTP/0.9.
1315    ///
1316    /// # Returns
1317    ///
1318    /// - `bool` - Whether the version is HTTP/0.9.
1319    #[inline(always)]
1320    pub fn is_http0_9_version(&self) -> bool {
1321        self.get_version().is_http0_9()
1322    }
1323
1324    /// Checks whether the HTTP version is HTTP/1.0.
1325    ///
1326    /// # Returns
1327    ///
1328    /// - `bool` - Whether the version is HTTP/1.0.
1329    #[inline(always)]
1330    pub fn is_http1_0_version(&self) -> bool {
1331        self.get_version().is_http1_0()
1332    }
1333
1334    /// Checks whether the HTTP version is HTTP/1.1.
1335    ///
1336    /// # Returns
1337    ///
1338    /// - `bool` - Whether the version is HTTP/1.1.
1339    #[inline(always)]
1340    pub fn is_http1_1_version(&self) -> bool {
1341        self.get_version().is_http1_1()
1342    }
1343
1344    /// Checks whether the HTTP version is HTTP/2.
1345    ///
1346    /// # Returns
1347    ///
1348    /// - `bool` - Whether the version is HTTP/2.
1349    #[inline(always)]
1350    pub fn is_http2_version(&self) -> bool {
1351        self.get_version().is_http2()
1352    }
1353
1354    /// Checks whether the HTTP version is HTTP/3.
1355    ///
1356    /// # Returns
1357    ///
1358    /// - `bool` - Whether the version is HTTP/3.
1359    #[inline(always)]
1360    pub fn is_http3_version(&self) -> bool {
1361        self.get_version().is_http3()
1362    }
1363
1364    /// Checks if the HTTP version is HTTP/1.1 or higher.
1365    ///
1366    /// # Returns
1367    ///
1368    /// - `bool` - Whether the version is HTTP/1.1 or higher.
1369    #[inline(always)]
1370    pub fn is_http1_1_or_higher_version(&self) -> bool {
1371        self.get_version().is_http1_1_or_higher()
1372    }
1373
1374    /// Checks whether the version belongs to the HTTP family.
1375    ///
1376    /// # Returns
1377    ///
1378    /// - `bool` - Whether the version is HTTP.
1379    #[inline(always)]
1380    pub fn is_http_version(&self) -> bool {
1381        self.get_version().is_http()
1382    }
1383
1384    /// Checks whether the HTTP version is unknown.
1385    ///
1386    /// # Returns
1387    ///
1388    /// - `bool` - Whether the version is unknown.
1389    #[inline(always)]
1390    pub fn is_unknown_version(&self) -> bool {
1391        self.get_version().is_unknown()
1392    }
1393
1394    /// Checks whether the WebSocket upgrade is enabled for this request.
1395    ///
1396    /// This method determines if the `UPGRADE` header indicates a WebSocket connection.
1397    ///
1398    /// # Returns
1399    ///
1400    /// - `bool` - Whether WebSocket upgrade is enabled.
1401    #[inline(always)]
1402    pub fn is_ws_upgrade_type(&self) -> bool {
1403        self.get_upgrade_type().is_ws()
1404    }
1405
1406    /// Checks if the current upgrade type is HTTP/2 cleartext (h2c).
1407    ///
1408    /// # Returns
1409    ///
1410    /// - `bool` - Whether the upgrade type is h2c.
1411    #[inline(always)]
1412    pub fn is_h2c_upgrade_type(&self) -> bool {
1413        self.get_upgrade_type().is_h2c()
1414    }
1415
1416    /// Checks if the current upgrade type is TLS (any version).
1417    ///
1418    /// # Returns
1419    ///
1420    /// - `bool` - Whether the upgrade type is TLS.
1421    #[inline(always)]
1422    pub fn is_tls_upgrade_type(&self) -> bool {
1423        self.get_upgrade_type().is_tls()
1424    }
1425
1426    /// Checks whether the upgrade type is unknown.
1427    ///
1428    /// # Returns
1429    ///
1430    /// - `bool` - Whether the upgrade type is unknown.
1431    #[inline(always)]
1432    pub fn is_unknown_upgrade_type(&self) -> bool {
1433        self.get_upgrade_type().is_unknown()
1434    }
1435
1436    /// Determines if a keep-alive connection should be enabled for this request.
1437    ///
1438    /// This function checks the `Connection` header and the HTTP version to determine
1439    /// if keep-alive should be enabled. The logic is as follows:
1440    ///
1441    /// 1. If the `Connection` header exists:
1442    ///    - Returns `true` if the header value is "keep-alive" (case-insensitive).
1443    ///    - Returns `false` if the header value is "close" (case-insensitive).
1444    /// 2. If no `Connection` header is present:
1445    ///    - Returns `true` if the HTTP version is 1.1 or higher.
1446    ///    - Returns `false` otherwise.
1447    ///
1448    /// # Returns
1449    ///
1450    /// - `bool` - Whether keep-alive should be enabled.
1451    #[inline(always)]
1452    pub fn is_enable_keep_alive(&self) -> bool {
1453        if let Some(connection_value) = self.try_get_header_back(CONNECTION) {
1454            if connection_value.eq_ignore_ascii_case(KEEP_ALIVE) {
1455                return true;
1456            } else if connection_value.eq_ignore_ascii_case(CLOSE) {
1457                return self.is_ws_upgrade_type();
1458            }
1459        }
1460        self.is_http1_1_or_higher_version() || self.is_ws_upgrade_type()
1461    }
1462
1463    /// Determines if keep-alive should be disabled for this request.
1464    ///
1465    /// # Returns
1466    ///
1467    /// - `bool` - Whether keep-alive should be disabled.
1468    #[inline(always)]
1469    pub fn is_disable_keep_alive(&self) -> bool {
1470        !self.is_enable_keep_alive()
1471    }
1472}