Skip to main content

http_type/request/
impl.rs

1use super::*;
2
3/// Implements the `std::error::Error` trait for `RequestError`.
4impl 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<io::Error> for RequestError {
22    /// Converts an I/O error to a `RequestError`.
23    ///
24    /// # Arguments
25    ///
26    /// - `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: 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::ServerClosedConnection(status) => *status,
122            Self::IncompleteWebSocketFrame(status) => *status,
123            Self::RequestTooLong(status) => *status,
124            Self::PathTooLong(status) => *status,
125            Self::QueryTooLong(status) => *status,
126            Self::HeaderLineTooLong(status) => *status,
127            Self::TooManyHeaders(status) => *status,
128            Self::HeaderKeyTooLong(status) => *status,
129            Self::HeaderValueTooLong(status) => *status,
130            Self::ContentLengthTooLarge(status) => *status,
131            Self::InvalidContentLength(status) => *status,
132            Self::InvalidUrlScheme(status) => *status,
133            Self::InvalidUrlHost(status) => *status,
134            Self::InvalidUrlPort(status) => *status,
135            Self::InvalidUrlPath(status) => *status,
136            Self::InvalidUrlQuery(status) => *status,
137            Self::InvalidUrlFragment(status) => *status,
138            Self::ReadTimeout(status) => *status,
139            Self::WriteTimeout(status) => *status,
140            Self::TcpConnectionFailed(status) => *status,
141            Self::TlsHandshakeFailed(status) => *status,
142            Self::TlsCertificateInvalid(status) => *status,
143            Self::WebSocketFrameTooLarge(status) => *status,
144            Self::WebSocketOpcodeUnsupported(status) => *status,
145            Self::WebSocketMaskMissing(status) => *status,
146            Self::WebSocketPayloadCorrupted(status) => *status,
147            Self::WebSocketInvalidUtf8(status) => *status,
148            Self::WebSocketInvalidCloseCode(status) => *status,
149            Self::WebSocketInvalidExtension(status) => *status,
150            Self::HttpRequestPartsInsufficient(status) => *status,
151            Self::TcpStreamConnect(status) => *status,
152            Self::TlsConnectorBuild(status) => *status,
153            Self::InvalidUrl(status) => *status,
154            Self::ConfigReadError(status) => *status,
155            Self::TcpStreamConnectString(status) => *status,
156            Self::TlsConnectorBuildString(status) => *status,
157            Self::Request(_) => HttpStatus::BadRequest,
158            Self::Unknown(status) => *status,
159        }
160    }
161
162    /// Gets the numeric HTTP status code associated with this error.
163    ///
164    /// Returns the numeric status code (e.g., 400, 404, 500) that corresponds to this error.
165    ///
166    /// # Returns
167    ///
168    /// - `ResponseStatusCode` - The numeric HTTP status code.
169    pub fn get_http_status_code(&self) -> ResponseStatusCode {
170        self.get_http_status().code()
171    }
172}
173
174/// Implementation of `Default` trait for `RequestConfig`.
175impl Default for RequestConfig {
176    /// Creates a new `RequestConfig` with default secure settings.
177    ///
178    /// This constructor initializes the configuration with standard security limits
179    /// suitable for most HTTP request parsing scenarios.
180    ///
181    /// # Returns
182    ///
183    /// - `Self` - A new `RequestConfig` instance with default settings.
184    #[inline(always)]
185    fn default() -> Self {
186        Self {
187            buffer_size: DEFAULT_BUFFER_SIZE,
188            max_path_size: DEFAULT_MAX_PATH_SIZE,
189            max_header_count: DEFAULT_MAX_HEADER_COUNT,
190            max_header_key_size: DEFAULT_MAX_HEADER_KEY_SIZE,
191            max_header_value_size: DEFAULT_MAX_HEADER_VALUE_SIZE,
192            max_body_size: DEFAULT_MAX_BODY_SIZE,
193            read_timeout_ms: DEFAULT_READ_TIMEOUT_MS,
194        }
195    }
196}
197
198impl RequestConfig {
199    /// Creates a new `RequestConfig` from a JSON string.
200    ///
201    /// # Arguments
202    ///
203    /// - `C` - The configuration, which requires the `AsRef<str>` bound.
204    ///
205    /// # Returns
206    ///
207    /// - `Result<RequestConfig, serde_json::Error>` - The parsed `RequestConfig` or an error.
208    pub fn from_json<C>(json: C) -> Result<RequestConfig, serde_json::Error>
209    where
210        C: AsRef<str>,
211    {
212        serde_json::from_str(json.as_ref())
213    }
214
215    /// Creates a new `RequestConfig` with low-security settings.
216    ///
217    /// This constructor initializes the configuration with less restrictive limits
218    /// for environments where higher limits are needed.
219    ///
220    /// # Returns
221    ///
222    /// - `Self` - A new `RequestConfig` instance with low-security settings.
223    #[inline(always)]
224    pub fn low_security() -> Self {
225        Self {
226            buffer_size: DEFAULT_LOW_SECURITY_BUFFER_SIZE,
227            max_path_size: DEFAULT_LOW_SECURITY_MAX_PATH_SIZE,
228            max_header_count: DEFAULT_LOW_SECURITY_MAX_HEADER_COUNT,
229            max_header_key_size: DEFAULT_LOW_SECURITY_MAX_HEADER_KEY_SIZE,
230            max_header_value_size: DEFAULT_LOW_SECURITY_MAX_HEADER_VALUE_SIZE,
231            max_body_size: DEFAULT_LOW_SECURITY_MAX_BODY_SIZE,
232            read_timeout_ms: DEFAULT_LOW_SECURITY_READ_TIMEOUT_MS,
233        }
234    }
235
236    /// Creates a new `RequestConfig` with high-security settings.
237    ///
238    /// This constructor initializes the configuration with more restrictive limits
239    /// to provide maximum protection against various attacks in high-risk environments.
240    ///
241    /// # Returns
242    ///
243    /// - `Self` - A new `RequestConfig` instance with high-security settings.
244    #[inline(always)]
245    pub fn high_security() -> Self {
246        Self {
247            buffer_size: DEFAULT_HIGH_SECURITY_BUFFER_SIZE,
248            max_path_size: DEFAULT_HIGH_SECURITY_MAX_PATH_SIZE,
249            max_header_count: DEFAULT_HIGH_SECURITY_MAX_HEADER_COUNT,
250            max_header_key_size: DEFAULT_HIGH_SECURITY_MAX_HEADER_KEY_SIZE,
251            max_header_value_size: DEFAULT_HIGH_SECURITY_MAX_HEADER_VALUE_SIZE,
252            max_body_size: DEFAULT_HIGH_SECURITY_MAX_BODY_SIZE,
253            read_timeout_ms: DEFAULT_HIGH_SECURITY_READ_TIMEOUT_MS,
254        }
255    }
256}
257
258/// Provides a default value for `Request`.
259///
260/// Returns a new `Request` instance with all fields initialized to their default values.
261impl Default for Request {
262    /// Builds the default `Request` with all fields set to their defaults.
263    #[inline(always)]
264    fn default() -> Self {
265        Self {
266            method: Method::default(),
267            host: String::new(),
268            version: HttpVersion::default(),
269            path: String::new(),
270            querys: hash_map_xx_hash3_64(),
271            headers: hash_map_xx_hash3_64(),
272            body: Vec::new(),
273        }
274    }
275}
276
277impl Request {
278    /// Resets the request to its default state while retaining allocated capacity.
279    ///
280    /// This keeps the header map, query map, body, and string allocations so
281    /// persistent (keep-alive) connections avoid repeated allocation per request.
282    ///
283    /// # Returns
284    ///
285    /// - `&mut Self` - A mutable reference to self for chaining.
286    pub fn reset(&mut self) -> &mut Self {
287        self.set_method(Method::default());
288        self.get_mut_host().clear();
289        self.set_version(HttpVersion::default());
290        self.get_mut_path().clear();
291        self.get_mut_querys().clear();
292        self.recycle_headers();
293        self.get_mut_body().clear();
294        self
295    }
296
297    /// Hands the header entries to the pool and empties the header map.
298    ///
299    /// The map ends up empty, exactly as clearing it would, but the name and
300    /// the value buffers of every header survive in the pool. The next
301    /// request on the same connection takes them back and overwrites them,
302    /// so a connection that keeps its headers stops allocating for them.
303    ///
304    /// # Returns
305    ///
306    /// - `()` - The headers have been recycled.
307    fn recycle_headers(&mut self) {
308        let headers: &mut RequestHeaders = self.get_mut_headers();
309        if headers.is_empty() {
310            return;
311        }
312        for (key, values) in headers.drain() {
313            return_header_entry((key, values));
314        }
315    }
316
317    /// Parses the first line of HTTP request into method, path, and version components.
318    ///
319    /// # Arguments
320    ///
321    /// - `&str` - The first line string of HTTP request to parse.
322    ///
323    /// # Returns
324    ///
325    /// - `Result<(RequestMethod, &str, RequestVersion), RequestError>` - A tuple containing:
326    ///   - The parsed HTTP method
327    ///   - The full path string
328    ///   - The parsed HTTP version
329    ///   - Or an error if parsing fails
330    #[inline(always)]
331    pub(crate) fn get_http_first_line(
332        line: &str,
333    ) -> Result<(RequestMethod, &str, RequestVersion), RequestError> {
334        let mut parts: SplitWhitespace<'_> = line.split_whitespace();
335        let method_str: &str = parts
336            .next()
337            .ok_or(RequestError::HttpRequestPartsInsufficient(
338                HttpStatus::BadRequest,
339            ))?;
340        let full_path: &str = parts
341            .next()
342            .ok_or(RequestError::HttpRequestPartsInsufficient(
343                HttpStatus::BadRequest,
344            ))?;
345        let version_str: &str = parts
346            .next()
347            .ok_or(RequestError::HttpRequestPartsInsufficient(
348                HttpStatus::BadRequest,
349            ))?;
350        let method: RequestMethod = method_str
351            .parse::<RequestMethod>()
352            .unwrap_or(Method::Unknown(method_str.to_string()));
353        let version: RequestVersion = version_str
354            .parse::<RequestVersion>()
355            .unwrap_or(RequestVersion::Unknown(version_str.to_string()));
356        Ok((method, full_path, version))
357    }
358
359    /// Validates the path length against the maximum allowed size.
360    ///
361    /// # Arguments
362    ///
363    /// - `&str` - The path string to check.
364    /// - `usize` - The maximum allowed path size.
365    ///
366    /// # Returns
367    ///
368    /// - `Result<(), RequestError>` - Ok if valid, or an error if the path is too long.
369    #[inline(always)]
370    pub(crate) fn check_http_path_size(path: &str, max_size: usize) -> Result<(), RequestError> {
371        if path.len() > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_PATH_SIZE {
372            return Err(RequestError::PathTooLong(HttpStatus::URITooLong));
373        }
374        Ok(())
375    }
376
377    /// Parses the query string from the full path.
378    ///
379    /// Handles both query parameters (after `?`) and hash fragments (after `#`),
380    /// ensuring proper parsing when both are present.
381    ///
382    /// # Arguments
383    ///
384    /// - `&str` - The full path string containing the query.
385    /// - `Option<usize>` - The index of the query separator (`?`), if present.
386    /// - `Option<usize>` - The index of the hash separator (`#`), if present.
387    ///
388    /// # Returns
389    ///
390    /// - `&str` - The parsed query string slice, or empty string if no query.
391    #[inline(always)]
392    pub(crate) fn get_http_query(
393        path: &str,
394        query_index: Option<usize>,
395        hash_index: Option<usize>,
396    ) -> &str {
397        query_index.map_or(EMPTY_STR, |query_index: usize| {
398            let temp: &str = &path[query_index + 1..];
399            match hash_index {
400                None => temp,
401                Some(hash_index) if hash_index <= query_index => temp,
402                Some(hash_index) => &temp[..hash_index - query_index - 1],
403            }
404        })
405    }
406
407    /// Parses the request path without query string or hash fragment.
408    ///
409    /// # Arguments
410    ///
411    /// - `&str` - The full path string.
412    /// - `Option<usize>` - The index of the query separator (`?`), if present.
413    /// - `Option<usize>` - The index of the hash separator (`#`), if present.
414    ///
415    /// # Returns
416    ///
417    /// - `&str` - The request path slice without query or hash.
418    #[inline(always)]
419    pub(crate) fn get_http_path(
420        path: &str,
421        query_index: Option<usize>,
422        hash_index: Option<usize>,
423    ) -> &str {
424        match query_index.or(hash_index) {
425            Some(separator_index) => &path[..separator_index],
426            None => path,
427        }
428    }
429
430    /// Parses a query string as_ref key-value pairs into the given map.
431    ///
432    /// Expects format "key1=value1&key2=value2". Empty values are allowed, and a
433    /// key that repeats keeps every value instead of letting the last one win.
434    /// The target map is expected to be empty; entries are inserted without
435    /// reallocating the map when it already has sufficient capacity.
436    ///
437    /// # Arguments
438    ///
439    /// - `&str` - The query string to parse.
440    /// - `&mut RequestQuerys` - The map to insert parsed parameters into.
441    #[inline(always)]
442    pub(crate) fn fill_http_querys(query: &str, querys: &mut RequestQuerys) {
443        if query.is_empty() {
444            return;
445        }
446        for pair in query.split(AND) {
447            if let Some((key, value)) = pair.split_once(EQUAL) {
448                if !key.is_empty() {
449                    querys
450                        .entry(key.to_string())
451                        .or_default()
452                        .push_back(value.to_string());
453                }
454            } else if !pair.is_empty() {
455                querys.entry(pair.to_string()).or_default();
456            }
457        }
458    }
459
460    /// Checks if the header count exceeds the maximum allowed.
461    ///
462    /// # Arguments
463    ///
464    /// - `usize` - The current number of headers parsed.
465    /// - `usize` - The maximum allowed number of headers.
466    ///
467    /// # Returns
468    ///
469    /// - `Result<(), RequestError>` - Returns an error if the limit is exceeded and not in low security mode.
470    #[inline(always)]
471    pub(crate) fn check_http_header_count(
472        count: usize,
473        max_count: usize,
474    ) -> Result<(), RequestError> {
475        if count > max_count && max_count != DEFAULT_LOW_SECURITY_MAX_HEADER_COUNT {
476            return Err(RequestError::TooManyHeaders(
477                HttpStatus::RequestHeaderFieldsTooLarge,
478            ));
479        }
480        Ok(())
481    }
482
483    /// Checks if a header key exceeds the maximum allowed length.
484    ///
485    /// # Arguments
486    ///
487    /// - `&str` - The header key to check.
488    /// - `usize` - The maximum allowed length for a header key.
489    ///
490    /// # Returns
491    ///
492    /// - `Result<(), RequestError>` - Returns an error if the limit is exceeded and not in low security mode.
493    #[inline(always)]
494    pub(crate) fn check_http_header_key_size(
495        key: &str,
496        max_size: usize,
497    ) -> Result<(), RequestError> {
498        if key.len() > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_HEADER_KEY_SIZE {
499            return Err(RequestError::HeaderKeyTooLong(
500                HttpStatus::RequestHeaderFieldsTooLarge,
501            ));
502        }
503        Ok(())
504    }
505
506    /// Checks if a header value exceeds the maximum allowed length.
507    ///
508    /// # Arguments
509    ///
510    /// - `&str` - The header value to check.
511    /// - `usize` - The maximum allowed length for a header value.
512    ///
513    /// # Returns
514    ///
515    /// - `Result<(), RequestError>` - Returns an error if the limit is exceeded and not in low security mode.
516    #[inline(always)]
517    pub(crate) fn check_http_header_value_size(
518        value: &str,
519        max_size: usize,
520    ) -> Result<(), RequestError> {
521        if value.len() > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_HEADER_VALUE_SIZE {
522            return Err(RequestError::HeaderValueTooLong(
523                HttpStatus::RequestHeaderFieldsTooLarge,
524            ));
525        }
526        Ok(())
527    }
528
529    /// Parses the Content-Length header value and checks it against max body size.
530    ///
531    /// # Arguments
532    ///
533    /// - `&str` - The Content-Length header value string.
534    /// - `usize` - The maximum allowed body size.
535    ///
536    /// # Returns
537    ///
538    /// - `Result<usize, RequestError>` - The parsed content length or an error.
539    #[inline(always)]
540    pub(crate) fn check_http_body_size(
541        value: &str,
542        max_size: usize,
543    ) -> Result<usize, RequestError> {
544        let length: usize = value.parse::<usize>()?;
545        if length > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_BODY_SIZE {
546            return Err(RequestError::ContentLengthTooLarge(
547                HttpStatus::PayloadTooLarge,
548            ));
549        }
550        Ok(length)
551    }
552
553    /// Parses HTTP headers from a buffered reader into this request.
554    ///
555    /// This method reads header lines from the provided buffered reader until an empty line
556    /// is encountered, which indicates the end of headers. It checks header count, length,
557    /// and content according to the provided configuration. The request's headers map and
558    /// host string are expected to be empty; they are filled without reallocating when they
559    /// already have sufficient capacity.
560    ///
561    /// The line buffer belongs to the caller so that a keep-alive connection
562    /// reads every header line of every request into the same allocation.
563    ///
564    /// # Arguments
565    ///
566    /// - `&mut R` - A mutable reference to a buffered reader, which requires the
567    ///   `AsyncBufReadExt + Unpin` bound.
568    /// - `&RequestConfig` - Configuration for security limits and buffer settings.
569    /// - `&mut String` - The buffer the header lines are read into.
570    ///
571    /// # Returns
572    ///
573    /// - `Result<usize, RequestError>` - The content length parsed from the
574    ///   Content-Length header, or an error if parsing fails.
575    pub(crate) async fn get_http_headers<R>(
576        &mut self,
577        reader: &mut R,
578        config: &RequestConfig,
579        header_line_buffer: &mut String,
580    ) -> Result<usize, RequestError>
581    where
582        R: AsyncBufReadExt + Unpin,
583    {
584        let Request { headers, host, .. } = self;
585        let max_header_count: usize = config.get_max_header_count();
586        let max_header_key_size: usize = config.get_max_header_key_size();
587        let max_header_value_size: usize = config.get_max_header_value_size();
588        let max_body_size: usize = config.get_max_body_size();
589        let mut content_size: usize = 0;
590        let mut header_count: usize = 0;
591        loop {
592            header_line_buffer.clear();
593            AsyncBufReadExt::read_line(reader, header_line_buffer).await?;
594            let header_line: &str = header_line_buffer.trim();
595            if header_line.is_empty() {
596                break;
597            }
598            header_count += 1;
599            Self::check_http_header_count(header_count, max_header_count)?;
600            let (key_part, value_part): (&str, &str) = match header_line.split_once(COLON) {
601                Some(parts) => parts,
602                None => continue,
603            };
604            let key_trimmed: &str = key_part.trim();
605            if key_trimmed.is_empty() {
606                continue;
607            }
608            Self::check_http_header_key_size(key_trimmed, max_header_key_size)?;
609            let value: &str = value_part.trim();
610            Self::check_http_header_value_size(value, max_header_value_size)?;
611            match key_trimmed {
612                key if key.eq_ignore_ascii_case(HOST) => {
613                    host.clear();
614                    host.push_str(value);
615                }
616                key if key.eq_ignore_ascii_case(CONTENT_LENGTH) => {
617                    content_size = Self::check_http_body_size(value, max_body_size)?;
618                }
619                _ => {}
620            }
621            Self::insert_http_header(headers, key_trimmed, value);
622        }
623        Ok(content_size)
624    }
625
626    /// Stores one header, reusing a pooled name and value where possible.
627    ///
628    /// The name is lowercased into the buffer of a recycled entry and the
629    /// value is written into that entry's value buffer, so a header that was
630    /// already seen on this connection costs no allocation at all.
631    ///
632    /// # Arguments
633    ///
634    /// - `&mut RequestHeaders` - The header map to store the header in.
635    /// - `&str` - The header name, as it arrived.
636    /// - `&str` - The header value.
637    fn insert_http_header(headers: &mut RequestHeaders, key: &str, value: &str) {
638        let (mut name, mut values): (String, VecDeque<String>) =
639            take_header_entry().unwrap_or_else(|| (String::new(), VecDeque::new()));
640        name.clear();
641        name.push_str(key);
642        name.make_ascii_lowercase();
643        match headers.entry(name) {
644            Entry::Occupied(mut occupied) => {
645                // The header repeats: it keeps every value it was given.
646                occupied.get_mut().push_back(value.to_string());
647                return_header_entry((String::new(), values));
648            }
649            Entry::Vacant(vacant) => {
650                // A recycled entry may carry the values of a header that was
651                // sent more than once. Those values belong to that header, so
652                // only the first one is kept and the rest are dropped.
653                while values.len() > 1 {
654                    values.pop_back();
655                }
656                if values.is_empty() {
657                    values.push_back(String::new());
658                }
659                if let Some(slot) = values.front_mut() {
660                    slot.clear();
661                    slot.push_str(value);
662                }
663                vacant.insert(values);
664            }
665        }
666    }
667
668    /// Reads the request body from the buffered reader into the given buffer.
669    ///
670    /// The target buffer is cleared and resized to the expected content size,
671    /// retaining its allocation when it already has sufficient capacity.
672    ///
673    /// # Arguments
674    ///
675    /// - `&mut R` - The buffered reader to read from, which requires the `AsyncRead + Unpin` bound.
676    /// - `&mut RequestBody` - The buffer to read the body bytes into.
677    /// - `usize` - The expected content size.
678    ///
679    /// # Returns
680    ///
681    /// - `Result<(), RequestError>` - Ok on success, or an error if reading fails.
682    #[inline(always)]
683    pub(crate) async fn fill_http_body<R>(
684        reader: &mut R,
685        body: &mut RequestBody,
686        content_size: usize,
687    ) -> Result<(), RequestError>
688    where
689        R: AsyncRead + Unpin,
690    {
691        body.clear();
692        if content_size > 0 {
693            body.resize(content_size, 0);
694            AsyncReadExt::read_exact(reader, body).await?;
695        }
696        Ok(())
697    }
698
699    /// Tries to get a query parameter by key.
700    ///
701    /// The key type must implement AsRef<str> conversion. A key that repeats in
702    /// the query carries every one of its values.
703    ///
704    /// # Arguments
705    ///
706    /// - `K` - The query parameter key, which implements `AsRef<str>`.
707    ///
708    /// # Returns
709    ///
710    /// - `Option<RequestQuerysValue>` - Every value of the parameter if it exists.
711    #[inline(always)]
712    pub fn try_get_query<K>(&self, key: K) -> Option<RequestQuerysValue>
713    where
714        K: AsRef<str>,
715    {
716        self.get_querys().get(key.as_ref()).cloned()
717    }
718
719    /// Tries to get the first query parameter value by key.
720    ///
721    /// Use this when the parameter is expected to appear once; use
722    /// `try_get_query` when every value matters.
723    ///
724    /// # Arguments
725    ///
726    /// - `K` - The query parameter key, which implements `AsRef<str>`.
727    ///
728    /// # Returns
729    ///
730    /// - `Option<RequestQuerysValueItem>` - The first parameter value if it exists.
731    #[inline(always)]
732    pub fn try_get_query_front<K>(&self, key: K) -> Option<RequestQuerysValueItem>
733    where
734        K: AsRef<str>,
735    {
736        self.get_querys()
737            .get(key.as_ref())
738            .and_then(|values: &VecDeque<String>| values.front().cloned())
739    }
740
741    /// Tries to get the last query parameter value by key.
742    ///
743    /// # Arguments
744    ///
745    /// - `K` - The query parameter key, which implements `AsRef<str>`.
746    ///
747    /// # Returns
748    ///
749    /// - `Option<RequestQuerysValueItem>` - The last parameter value if it exists.
750    #[inline(always)]
751    pub fn try_get_query_back<K>(&self, key: K) -> Option<RequestQuerysValueItem>
752    where
753        K: AsRef<str>,
754    {
755        self.get_querys()
756            .get(key.as_ref())
757            .and_then(|values: &VecDeque<String>| values.back().cloned())
758    }
759
760    /// Tries to get the number of values of a query parameter.
761    ///
762    /// # Arguments
763    ///
764    /// - `K` - The query parameter key, which implements `AsRef<str>`.
765    ///
766    /// # Returns
767    ///
768    /// - `Option<usize>` - The number of values if the parameter exists.
769    #[inline(always)]
770    pub fn try_get_query_size<K>(&self, key: K) -> Option<usize>
771    where
772        K: AsRef<str>,
773    {
774        self.get_querys()
775            .get(key.as_ref())
776            .map(|values: &VecDeque<String>| values.len())
777    }
778
779    /// Checks whether a query parameter exists.
780    ///
781    /// # Arguments
782    ///
783    /// - `K` - The query parameter key, which implements `AsRef<str>`.
784    ///
785    /// # Returns
786    ///
787    /// - `bool` - Whether the parameter exists.
788    #[inline(always)]
789    pub fn has_query<K>(&self, key: K) -> bool
790    where
791        K: AsRef<str>,
792    {
793        self.get_querys().contains_key(key.as_ref())
794    }
795
796    /// Gets a query parameter by key.
797    ///
798    /// # Arguments
799    ///
800    /// - `K` - The query parameter key, which implements `AsRef<str>`.
801    ///
802    /// # Returns
803    ///
804    /// - `RequestQuerysValue` - Every value of the parameter.
805    ///
806    /// # Panics
807    ///
808    /// This function will panic if the query parameter key is not found.
809    #[inline(always)]
810    pub fn get_query<K>(&self, key: K) -> RequestQuerysValue
811    where
812        K: AsRef<str>,
813    {
814        self.try_get_query(key).unwrap()
815    }
816
817    /// Gets the first query parameter value by key.
818    ///
819    /// # Arguments
820    ///
821    /// - `K` - The query parameter key, which implements `AsRef<str>`.
822    ///
823    /// # Returns
824    ///
825    /// - `RequestQuerysValueItem` - The first parameter value.
826    ///
827    /// # Panics
828    ///
829    /// This function will panic if the query parameter key is not found.
830    #[inline(always)]
831    pub fn get_query_front<K>(&self, key: K) -> RequestQuerysValueItem
832    where
833        K: AsRef<str>,
834    {
835        self.try_get_query_front(key).unwrap()
836    }
837
838    /// Retrieves the number of query parameters.
839    ///
840    /// # Returns
841    ///
842    /// - `usize` - The count of distinct query parameter keys.
843    #[inline(always)]
844    pub fn get_querys_size(&self) -> usize {
845        self.get_querys().len()
846    }
847
848    /// Tries to retrieve the value of a request header by its key.
849    ///
850    /// The key is matched case-insensitively, because the parser stores every
851    /// header name lowercased and an HTTP header name is case-insensitive by
852    /// specification. Looking a header up with `Content-Type` and with
853    /// `content-type` therefore find the same value.
854    ///
855    /// # Arguments
856    ///
857    /// - `K` - The header's key, which must implement `AsRef<str>`.
858    ///
859    /// # Returns
860    ///
861    /// - `Option<RequestHeadersValue>` - The optional header values.
862    #[inline(always)]
863    pub fn try_get_header<K>(&self, key: K) -> Option<RequestHeadersValue>
864    where
865        K: AsRef<str>,
866    {
867        self.get_headers()
868            .get(&key.as_ref().to_ascii_lowercase())
869            .cloned()
870    }
871
872    /// Retrieves the value of a request header by its key.
873    ///
874    /// # Arguments
875    ///
876    /// - `K` - The header's key, which must implement `AsRef<str>`.
877    ///
878    /// # Returns
879    ///
880    /// - `RequestHeadersValue` - The optional header values.
881    ///
882    /// # Panics
883    ///
884    /// This function will panic if the header key is not found.
885    #[inline(always)]
886    pub fn get_header<K>(&self, key: K) -> RequestHeadersValue
887    where
888        K: AsRef<str>,
889    {
890        self.try_get_header(key).unwrap()
891    }
892
893    /// Tries to retrieve the first value of a request header by its key.
894    ///
895    /// # Arguments
896    ///
897    /// - `K` - The header's key, which must implement `AsRef<str>`.
898    ///
899    /// # Returns
900    ///
901    /// - `Option<RequestHeadersValueItem>` - The first header value if exists.
902    #[inline(always)]
903    pub fn try_get_header_front<K>(&self, key: K) -> Option<RequestHeadersValueItem>
904    where
905        K: AsRef<str>,
906    {
907        self.get_headers()
908            .get(&key.as_ref().to_ascii_lowercase())
909            .and_then(|header_values: &VecDeque<String>| header_values.front().cloned())
910    }
911
912    /// Retrieves the first value of a request header by its key.
913    ///
914    /// # Arguments
915    ///
916    /// - `K` - The header's key, which must implement `AsRef<str>`.
917    ///
918    /// # Returns
919    ///
920    /// - `RequestHeadersValueItem` - The first header value if exists.
921    ///
922    /// # Panics
923    ///
924    /// This function will panic if the header key is not found.
925    #[inline(always)]
926    pub fn get_header_front<K>(&self, key: K) -> RequestHeadersValueItem
927    where
928        K: AsRef<str>,
929    {
930        self.try_get_header_front(key).unwrap()
931    }
932
933    /// Tries to retrieve the last value of a request header by its key.
934    ///
935    /// # Arguments
936    ///
937    /// - `K` - The header's key, which must implement `AsRef<str>`.
938    ///
939    /// # Returns
940    ///
941    /// - `Option<RequestHeadersValueItem>` - The last header value if exists.
942    #[inline(always)]
943    pub fn try_get_header_back<K>(&self, key: K) -> Option<RequestHeadersValueItem>
944    where
945        K: AsRef<str>,
946    {
947        self.get_headers()
948            .get(&key.as_ref().to_ascii_lowercase())
949            .and_then(|header_values: &VecDeque<String>| header_values.back().cloned())
950    }
951
952    /// Retrieves the last value of a request header by its key.
953    ///
954    /// # Arguments
955    ///
956    /// - `K` - The header's key, which must implement `AsRef<str>`.
957    ///
958    /// # Returns
959    ///
960    /// - `RequestHeadersValueItem` - The last header value if exists.
961    ///
962    /// # Panics
963    ///
964    /// This function will panic if the header key is not found.
965    #[inline(always)]
966    pub fn get_header_back<K>(&self, key: K) -> RequestHeadersValueItem
967    where
968        K: AsRef<str>,
969    {
970        self.try_get_header_back(key).unwrap()
971    }
972
973    /// Tries to retrieve the number of values for a specific header.
974    ///
975    /// # Arguments
976    ///
977    /// - `K` - The header's key, which must implement `AsRef<str>`.
978    ///
979    /// # Returns
980    ///
981    /// - `Option<usize>` - The count of values for the header if exists.
982    #[inline(always)]
983    pub fn try_get_header_size<K>(&self, key: K) -> Option<usize>
984    where
985        K: AsRef<str>,
986    {
987        self.get_headers()
988            .get(&key.as_ref().to_ascii_lowercase())
989            .map(|header_values: &VecDeque<String>| header_values.len())
990    }
991
992    /// Retrieves the number of values for a specific header.
993    ///
994    /// # Arguments
995    ///
996    /// - `K` - The header's key, which must implement `AsRef<str>`.
997    ///
998    /// # Returns
999    ///
1000    /// - `usize` - The count of values for the header.
1001    ///
1002    /// # Panics
1003    ///
1004    /// This function will panic if the header key is not found.
1005    #[inline(always)]
1006    pub fn get_header_size<K>(&self, key: K) -> usize
1007    where
1008        K: AsRef<str>,
1009    {
1010        self.try_get_header_size(key).unwrap()
1011    }
1012
1013    /// Retrieves the total number of header values across all headers.
1014    ///
1015    /// # Returns
1016    ///
1017    /// - `usize` - The total count of all header values.
1018    #[inline(always)]
1019    pub fn get_headers_values_size(&self) -> usize {
1020        self.get_headers()
1021            .values()
1022            .map(|header_values: &VecDeque<String>| header_values.len())
1023            .sum()
1024    }
1025
1026    /// Retrieves the number of unique headers.
1027    ///
1028    /// # Returns
1029    ///
1030    /// - `usize` - The count of unique header keys.
1031    #[inline(always)]
1032    pub fn get_headers_size(&self) -> usize {
1033        self.get_headers().len()
1034    }
1035
1036    /// Checks if a specific header exists.
1037    ///
1038    /// # Arguments
1039    ///
1040    /// - `K` - The header key to check, which must implement `AsRef<str>`.
1041    ///
1042    /// # Returns
1043    ///
1044    /// - `bool` - Whether the header exists.
1045    #[inline(always)]
1046    pub fn has_header<K>(&self, key: K) -> bool
1047    where
1048        K: AsRef<str>,
1049    {
1050        self.get_headers()
1051            .contains_key(&key.as_ref().to_ascii_lowercase())
1052    }
1053
1054    /// Checks if a header contains a specific value.
1055    ///
1056    /// # Arguments
1057    ///
1058    /// - `K` - The header key to check, which must implement `AsRef<str>`.
1059    /// - `V` - The value to search for, which must implement `AsRef<str>`.
1060    ///
1061    /// # Returns
1062    ///
1063    /// - `bool` - Whether the header contains the value.
1064    #[inline(always)]
1065    pub fn has_header_value<K, V>(&self, key: K, value: V) -> bool
1066    where
1067        K: AsRef<str>,
1068        V: AsRef<str>,
1069    {
1070        if let Some(values) = self.get_headers().get(&key.as_ref().to_ascii_lowercase()) {
1071            values.iter().any(|data: &String| data == value.as_ref())
1072        } else {
1073            false
1074        }
1075    }
1076
1077    /// Tries to parse cookies from the `Cookie` header.
1078    ///
1079    /// This method retrieves the `Cookie` header value and parses it into
1080    /// a collection of key-value pairs representing the cookies.
1081    ///
1082    /// # Returns
1083    ///
1084    /// - `Option<Cookies>` - The parsed cookies if the header exists, otherwise `None`.
1085    #[inline(always)]
1086    pub fn try_get_cookies(&self) -> Option<Cookies> {
1087        self.try_get_header_back(COOKIE)
1088            .map(|cookie_header: String| Cookie::parse(cookie_header))
1089    }
1090
1091    /// Parses cookies from the `Cookie` header.
1092    ///
1093    /// This method retrieves the `Cookie` header value and parses it into
1094    /// a collection of key-value pairs representing the cookies.
1095    ///
1096    /// # Returns
1097    ///
1098    /// - `Cookies` - The parsed cookies.
1099    ///
1100    /// # Panics
1101    ///
1102    /// This function will panic if the `Cookie` header is not found.
1103    #[inline(always)]
1104    pub fn get_cookies(&self) -> Cookies {
1105        self.try_get_cookies().unwrap()
1106    }
1107
1108    /// Tries to get a cookie value by its key.
1109    ///
1110    /// This method first parses the cookies from the `Cookie` header,
1111    /// then attempts to retrieve the value for the specified key.
1112    ///
1113    /// # Arguments
1114    ///
1115    /// - `K` - The cookie key, which implements `AsRef<str>`.
1116    ///
1117    /// # Returns
1118    ///
1119    /// - `Option<CookieValue>` - The cookie value if exists.
1120    #[inline(always)]
1121    pub fn try_get_cookie<K>(&self, key: K) -> Option<CookieValue>
1122    where
1123        K: AsRef<str>,
1124    {
1125        self.try_get_cookies()
1126            .and_then(|cookies: Cookies| cookies.get(key.as_ref()).cloned())
1127    }
1128
1129    /// Gets a cookie value by its key.
1130    ///
1131    /// This method first parses the cookies from the `Cookie` header,
1132    /// then retrieves the value for the specified key.
1133    ///
1134    /// # Arguments
1135    ///
1136    /// - `K` - The cookie key, which implements `AsRef<str>`.
1137    ///
1138    /// # Returns
1139    ///
1140    /// - `CookieValue` - The cookie value.
1141    ///
1142    /// # Panics
1143    ///
1144    /// This function will panic if the `Cookie` header is not found
1145    /// or the cookie key does not exist.
1146    #[inline(always)]
1147    pub fn get_cookie<K>(&self, key: K) -> CookieValue
1148    where
1149        K: AsRef<str>,
1150    {
1151        self.try_get_cookie(key).unwrap()
1152    }
1153
1154    /// Retrieves the upgrade type from the request headers.
1155    ///
1156    /// This method looks for the `UPGRADE` header and attempts to parse its value
1157    /// as_ref an `UpgradeType`. If the header is missing or the value is invalid,
1158    /// it returns the default `UpgradeType`.
1159    ///
1160    /// # Returns
1161    ///
1162    /// - `UpgradeType` - The parsed upgrade type.
1163    #[inline(always)]
1164    pub fn get_upgrade_type(&self) -> UpgradeType {
1165        self.try_get_header_back(UPGRADE)
1166            .and_then(|data: String| data.parse::<UpgradeType>().ok())
1167            .unwrap_or_default()
1168    }
1169
1170    /// Retrieves the body content of the request as a UTF-8 encoded string.
1171    ///
1172    /// This method uses `String::from_utf8_lossy` to convert the byte slice returned by `self.get_body()` as a string.
1173    /// If the byte slice contains invalid UTF-8 sequences, they will be replaced with the Unicode replacement character ().
1174    ///
1175    /// # Returns
1176    ///
1177    /// - `String` - The body content as a string.
1178    #[inline(always)]
1179    pub fn get_body_string(&self) -> String {
1180        String::from_utf8_lossy(self.get_body()).into_owned()
1181    }
1182
1183    /// Deserializes the body content of the request as_ref a specified type `T`.
1184    ///
1185    /// This method first retrieves the body content as a byte slice using `self.get_body()`.
1186    /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
1187    ///
1188    /// The target type `T` is a type parameter of this method and must implement `DeserializeOwned`.
1189    ///
1190    /// # Returns
1191    ///
1192    /// - `Result<T, serde_json::Error>` - The deserialization result.
1193    #[inline(always)]
1194    pub fn try_get_body_json<T>(&self) -> Result<T, serde_json::Error>
1195    where
1196        T: DeserializeOwned,
1197    {
1198        serde_json::from_slice(self.get_body())
1199    }
1200
1201    /// Deserializes the body content of the request as_ref a specified type `T`.
1202    ///
1203    /// This method first retrieves the body content as a byte slice using `self.get_body()`.
1204    /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
1205    ///
1206    /// The target type `T` is a type parameter of this method and must implement `DeserializeOwned`.
1207    ///
1208    /// # Returns
1209    ///
1210    /// - `T` - The deserialized body content.
1211    ///
1212    /// # Panics
1213    ///
1214    /// This function will panic if the deserialization fails.
1215    #[inline(always)]
1216    pub fn get_body_json<T>(&self) -> T
1217    where
1218        T: DeserializeOwned,
1219    {
1220        self.try_get_body_json().unwrap()
1221    }
1222
1223    /// Checks whether the WebSocket upgrade is enabled for this request.
1224    ///
1225    /// This method determines if the `UPGRADE` header indicates a WebSocket connection.
1226    ///
1227    /// # Returns
1228    ///
1229    /// - `bool` - Whether WebSocket upgrade is enabled.
1230    #[inline(always)]
1231    pub fn is_ws_upgrade_type(&self) -> bool {
1232        self.get_upgrade_type().is_ws()
1233    }
1234
1235    /// Checks whether the request declares a `multipart/form-data` body.
1236    ///
1237    /// # Returns
1238    ///
1239    /// - `bool` - Whether the request content type is `multipart/form-data`.
1240    #[inline(always)]
1241    pub fn is_multipart_form_data(&self) -> bool {
1242        self.try_get_content_type()
1243            .map(|content_type: String| MultipartFormData::is_form_data(content_type))
1244            .unwrap_or(false)
1245    }
1246
1247    /// Tries to get the request content type with its parameters stripped.
1248    ///
1249    /// A `Content-Type` header such as `text/html; charset=utf-8` yields the
1250    /// media type alone, so a caller comparing against a media type does not
1251    /// have to know that parameters may follow it.
1252    ///
1253    /// # Returns
1254    ///
1255    /// - `Option<RequestContentType>` - The media type, or `None` when the header is absent.
1256    #[inline(always)]
1257    pub fn try_get_content_type(&self) -> Option<RequestContentType> {
1258        self.try_get_header_front(CONTENT_TYPE)
1259            .map(|value: String| {
1260                value
1261                    .split(SEMICOLON)
1262                    .next()
1263                    .unwrap_or(EMPTY_STR)
1264                    .trim()
1265                    .to_ascii_lowercase()
1266            })
1267    }
1268
1269    /// Tries to get one parameter of the request `Content-Type` header.
1270    ///
1271    /// The name is matched case-insensitively and a quoted value is unquoted,
1272    /// so both `boundary=abc` and `boundary="abc"` yield `abc`.
1273    ///
1274    /// # Arguments
1275    ///
1276    /// - `K` - The parameter name, which requires the `AsRef<str>` bound.
1277    ///
1278    /// # Returns
1279    ///
1280    /// - `Option<RequestContentTypeParameter>` - The parameter value, or `None` when absent.
1281    pub fn try_get_content_type_parameter<K>(&self, name: K) -> Option<RequestContentTypeParameter>
1282    where
1283        K: AsRef<str>,
1284    {
1285        let content_type: String = self.try_get_header_front(CONTENT_TYPE)?;
1286        let name: &str = name.as_ref();
1287        for parameter in content_type.split(SEMICOLON).skip(1) {
1288            let (key, value) = parameter.trim().split_once(EQUAL)?;
1289            if !key.trim().eq_ignore_ascii_case(name) {
1290                continue;
1291            }
1292            let value: &str = value.trim();
1293            let value: &str = value
1294                .strip_prefix(MULTIPART_PARAMETER_QUOTE)
1295                .and_then(|value: &str| value.strip_suffix(MULTIPART_PARAMETER_QUOTE))
1296                .unwrap_or(value);
1297            if !value.is_empty() {
1298                return Some(value.to_string());
1299            }
1300        }
1301        None
1302    }
1303
1304    /// Tries to decode a `multipart/form-data` body into its parts.
1305    ///
1306    /// The boundary is read from the request `Content-Type` header rather than
1307    /// guessed, so a body whose content type declares no boundary, a truncated
1308    /// body, and a part without a name all yield `None`.
1309    ///
1310    /// # Returns
1311    ///
1312    /// - `Option<MultipartFormDataParts>` - The decoded parts, or `None` when unavailable.
1313    pub fn try_get_body_form_data(&self) -> Option<MultipartFormDataParts> {
1314        let boundary: MultipartFormDataBoundary =
1315            self.try_get_content_type_parameter(MULTIPART_BOUNDARY_PARAMETER)?;
1316        MultipartFormData::parse(self.get_body(), &boundary)
1317    }
1318
1319    /// Decodes an `application/x-www-form-urlencoded` body into its fields.
1320    ///
1321    /// # Returns
1322    ///
1323    /// - `BodyForm` - The decoded form fields.
1324    #[inline(always)]
1325    pub fn get_body_form(&self) -> BodyForm {
1326        MultipartFormData::parse_url_encoded(self.get_body())
1327    }
1328
1329    /// Tries to get a plain text field of a `multipart/form-data` body.
1330    ///
1331    /// A part that uploads a file is skipped, so a file field never silently
1332    /// decodes as text.
1333    ///
1334    /// # Arguments
1335    ///
1336    /// - `K` - The form field name, which requires the `AsRef<str>` bound.
1337    ///
1338    /// # Returns
1339    ///
1340    /// - `Option<BodyFormValue>` - The field value, or `None` when absent or a file.
1341    pub fn try_get_body_form_data_text<K>(&self, name: K) -> Option<BodyFormValue>
1342    where
1343        K: AsRef<str>,
1344    {
1345        let parts: MultipartFormDataParts = self.try_get_body_form_data()?;
1346        MultipartFormData::try_get_part_text(&parts, name)
1347    }
1348
1349    /// Checks if the current upgrade type is HTTP/2 cleartext (h2c).
1350    ///
1351    /// # Returns
1352    ///
1353    /// - `bool` - Whether the upgrade type is h2c.
1354    #[inline(always)]
1355    pub fn is_h2c_upgrade_type(&self) -> bool {
1356        self.get_upgrade_type().is_h2c()
1357    }
1358
1359    /// Checks if the current upgrade type is TLS (any version).
1360    ///
1361    /// # Returns
1362    ///
1363    /// - `bool` - Whether the upgrade type is TLS.
1364    #[inline(always)]
1365    pub fn is_tls_upgrade_type(&self) -> bool {
1366        self.get_upgrade_type().is_tls()
1367    }
1368
1369    /// Checks whether the upgrade type is unknown.
1370    ///
1371    /// # Returns
1372    ///
1373    /// - `bool` - Whether the upgrade type is unknown.
1374    #[inline(always)]
1375    pub fn is_unknown_upgrade_type(&self) -> bool {
1376        self.get_upgrade_type().is_unknown()
1377    }
1378
1379    /// Determines if a keep-alive connection should be enabled for this request.
1380    ///
1381    /// This function checks the `Connection` header and the HTTP version to determine
1382    /// if keep-alive should be enabled. The logic is as follows:
1383    ///
1384    /// 1. If the `Connection` header exists:
1385    ///    - Returns `true` if the header value is "keep-alive" (case-insensitive).
1386    ///    - Returns `false` if the header value is "close" (case-insensitive).
1387    /// 2. If no `Connection` header is present:
1388    ///    - Returns `true` if the HTTP version is 1.1 or higher.
1389    ///    - Returns `false` otherwise.
1390    ///
1391    /// # Returns
1392    ///
1393    /// - `bool` - Whether keep-alive should be enabled.
1394    #[inline(always)]
1395    pub fn is_enable_keep_alive(&self) -> bool {
1396        if let Some(connection_value) = self.try_get_header_back(CONNECTION) {
1397            if connection_value.eq_ignore_ascii_case(KEEP_ALIVE) {
1398                return true;
1399            } else if connection_value.eq_ignore_ascii_case(CLOSE) {
1400                return self.is_ws_upgrade_type();
1401            }
1402        }
1403        self.get_version().is_http1_1_or_higher() || self.is_ws_upgrade_type()
1404    }
1405
1406    /// Determines if keep-alive should be disabled for this request.
1407    ///
1408    /// # Returns
1409    ///
1410    /// - `bool` - Whether keep-alive should be disabled.
1411    #[inline(always)]
1412    pub fn is_disable_keep_alive(&self) -> bool {
1413        !self.is_enable_keep_alive()
1414    }
1415}