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.get_mut_headers().clear();
293        self.get_mut_body().clear();
294        self
295    }
296
297    /// Parses the first line of HTTP request into method, path, and version components.
298    ///
299    /// # Arguments
300    ///
301    /// - `&str` - The first line string of HTTP request to parse.
302    ///
303    /// # Returns
304    ///
305    /// - `Result<(RequestMethod, &str, RequestVersion), RequestError>` - A tuple containing:
306    ///   - The parsed HTTP method
307    ///   - The full path string
308    ///   - The parsed HTTP version
309    ///   - Or an error if parsing fails
310    #[inline(always)]
311    pub(crate) fn get_http_first_line(
312        line: &str,
313    ) -> Result<(RequestMethod, &str, RequestVersion), RequestError> {
314        let mut parts: SplitWhitespace<'_> = line.split_whitespace();
315        let method_str: &str = parts
316            .next()
317            .ok_or(RequestError::HttpRequestPartsInsufficient(
318                HttpStatus::BadRequest,
319            ))?;
320        let full_path: &str = parts
321            .next()
322            .ok_or(RequestError::HttpRequestPartsInsufficient(
323                HttpStatus::BadRequest,
324            ))?;
325        let version_str: &str = parts
326            .next()
327            .ok_or(RequestError::HttpRequestPartsInsufficient(
328                HttpStatus::BadRequest,
329            ))?;
330        let method: RequestMethod = method_str
331            .parse::<RequestMethod>()
332            .unwrap_or(Method::Unknown(method_str.to_string()));
333        let version: RequestVersion = version_str
334            .parse::<RequestVersion>()
335            .unwrap_or(RequestVersion::Unknown(version_str.to_string()));
336        Ok((method, full_path, version))
337    }
338
339    /// Validates the path length against the maximum allowed size.
340    ///
341    /// # Arguments
342    ///
343    /// - `&str` - The path string to check.
344    /// - `usize` - The maximum allowed path size.
345    ///
346    /// # Returns
347    ///
348    /// - `Result<(), RequestError>` - Ok if valid, or an error if the path is too long.
349    #[inline(always)]
350    pub(crate) fn check_http_path_size(path: &str, max_size: usize) -> Result<(), RequestError> {
351        if path.len() > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_PATH_SIZE {
352            return Err(RequestError::PathTooLong(HttpStatus::URITooLong));
353        }
354        Ok(())
355    }
356
357    /// Parses the query string from the full path.
358    ///
359    /// Handles both query parameters (after `?`) and hash fragments (after `#`),
360    /// ensuring proper parsing when both are present.
361    ///
362    /// # Arguments
363    ///
364    /// - `&str` - The full path string containing the query.
365    /// - `Option<usize>` - The index of the query separator (`?`), if present.
366    /// - `Option<usize>` - The index of the hash separator (`#`), if present.
367    ///
368    /// # Returns
369    ///
370    /// - `&str` - The parsed query string slice, or empty string if no query.
371    #[inline(always)]
372    pub(crate) fn get_http_query(
373        path: &str,
374        query_index: Option<usize>,
375        hash_index: Option<usize>,
376    ) -> &str {
377        query_index.map_or(EMPTY_STR, |query_index: usize| {
378            let temp: &str = &path[query_index + 1..];
379            match hash_index {
380                None => temp,
381                Some(hash_index) if hash_index <= query_index => temp,
382                Some(hash_index) => &temp[..hash_index - query_index - 1],
383            }
384        })
385    }
386
387    /// Parses the request path without query string or hash fragment.
388    ///
389    /// # Arguments
390    ///
391    /// - `&str` - The full path string.
392    /// - `Option<usize>` - The index of the query separator (`?`), if present.
393    /// - `Option<usize>` - The index of the hash separator (`#`), if present.
394    ///
395    /// # Returns
396    ///
397    /// - `&str` - The request path slice without query or hash.
398    #[inline(always)]
399    pub(crate) fn get_http_path(
400        path: &str,
401        query_index: Option<usize>,
402        hash_index: Option<usize>,
403    ) -> &str {
404        match query_index.or(hash_index) {
405            Some(separator_index) => &path[..separator_index],
406            None => path,
407        }
408    }
409
410    /// Parses a query string as_ref key-value pairs into the given map.
411    ///
412    /// Expects format "key1=value1&key2=value2". Empty values are allowed.
413    /// The target map is expected to be empty; entries are inserted without
414    /// reallocating the map when it already has sufficient capacity.
415    ///
416    /// # Arguments
417    ///
418    /// - `&str` - The query string to parse.
419    /// - `&mut RequestQuerys` - The map to insert parsed parameters into.
420    #[inline(always)]
421    pub(crate) fn fill_http_querys(query: &str, querys: &mut RequestQuerys) {
422        if query.is_empty() {
423            return;
424        }
425        for pair in query.split(AND) {
426            if let Some((key, value)) = pair.split_once(EQUAL) {
427                if !key.is_empty() {
428                    querys.insert(key.to_string(), value.to_string());
429                }
430            } else if !pair.is_empty() {
431                querys.insert(pair.to_string(), String::new());
432            }
433        }
434    }
435
436    /// Checks if the header count exceeds the maximum allowed.
437    ///
438    /// # Arguments
439    ///
440    /// - `usize` - The current number of headers parsed.
441    /// - `usize` - The maximum allowed number of headers.
442    ///
443    /// # Returns
444    ///
445    /// - `Result<(), RequestError>` - Returns an error if the limit is exceeded and not in low security mode.
446    #[inline(always)]
447    pub(crate) fn check_http_header_count(
448        count: usize,
449        max_count: usize,
450    ) -> Result<(), RequestError> {
451        if count > max_count && max_count != DEFAULT_LOW_SECURITY_MAX_HEADER_COUNT {
452            return Err(RequestError::TooManyHeaders(
453                HttpStatus::RequestHeaderFieldsTooLarge,
454            ));
455        }
456        Ok(())
457    }
458
459    /// Checks if a header key exceeds the maximum allowed length.
460    ///
461    /// # Arguments
462    ///
463    /// - `&str` - The header key to check.
464    /// - `usize` - The maximum allowed length for a header key.
465    ///
466    /// # Returns
467    ///
468    /// - `Result<(), RequestError>` - Returns an error if the limit is exceeded and not in low security mode.
469    #[inline(always)]
470    pub(crate) fn check_http_header_key_size(
471        key: &str,
472        max_size: usize,
473    ) -> Result<(), RequestError> {
474        if key.len() > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_HEADER_KEY_SIZE {
475            return Err(RequestError::HeaderKeyTooLong(
476                HttpStatus::RequestHeaderFieldsTooLarge,
477            ));
478        }
479        Ok(())
480    }
481
482    /// Checks if a header value exceeds the maximum allowed length.
483    ///
484    /// # Arguments
485    ///
486    /// - `&str` - The header value to check.
487    /// - `usize` - The maximum allowed length for a header value.
488    ///
489    /// # Returns
490    ///
491    /// - `Result<(), RequestError>` - Returns an error if the limit is exceeded and not in low security mode.
492    #[inline(always)]
493    pub(crate) fn check_http_header_value_size(
494        value: &str,
495        max_size: usize,
496    ) -> Result<(), RequestError> {
497        if value.len() > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_HEADER_VALUE_SIZE {
498            return Err(RequestError::HeaderValueTooLong(
499                HttpStatus::RequestHeaderFieldsTooLarge,
500            ));
501        }
502        Ok(())
503    }
504
505    /// Parses the Content-Length header value and checks it against max body size.
506    ///
507    /// # Arguments
508    ///
509    /// - `&str` - The Content-Length header value string.
510    /// - `usize` - The maximum allowed body size.
511    ///
512    /// # Returns
513    ///
514    /// - `Result<usize, RequestError>` - The parsed content length or an error.
515    #[inline(always)]
516    pub(crate) fn check_http_body_size(
517        value: &str,
518        max_size: usize,
519    ) -> Result<usize, RequestError> {
520        let length: usize = value.parse::<usize>()?;
521        if length > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_BODY_SIZE {
522            return Err(RequestError::ContentLengthTooLarge(
523                HttpStatus::PayloadTooLarge,
524            ));
525        }
526        Ok(length)
527    }
528
529    /// Parses HTTP headers from a buffered reader into this request.
530    ///
531    /// This method reads header lines from the provided buffered reader until an empty line
532    /// is encountered, which indicates the end of headers. It checks header count, length,
533    /// and content according to the provided configuration. The request's headers map and
534    /// host string are expected to be empty; they are filled without reallocating when they
535    /// already have sufficient capacity.
536    ///
537    /// # Arguments
538    ///
539    /// - `&mut R` - A mutable reference to a buffered reader, which requires the
540    ///   `AsyncBufReadExt + Unpin` bound.
541    /// - `&RequestConfig` - Configuration for security limits and buffer settings.
542    ///
543    /// # Returns
544    ///
545    /// - `Result<usize, RequestError>` - The content length parsed from the
546    ///   Content-Length header, or an error if parsing fails.
547    pub(crate) async fn get_http_headers<R>(
548        &mut self,
549        reader: &mut R,
550        config: &RequestConfig,
551    ) -> Result<usize, RequestError>
552    where
553        R: AsyncBufReadExt + Unpin,
554    {
555        let Request { headers, host, .. } = self;
556        let max_header_count: usize = config.get_max_header_count();
557        let max_header_key_size: usize = config.get_max_header_key_size();
558        let max_header_value_size: usize = config.get_max_header_value_size();
559        let max_body_size: usize = config.get_max_body_size();
560        let mut content_size: usize = 0;
561        let mut header_count: usize = 0;
562        let mut header_line_buffer: String = String::with_capacity(HEADER_LINE_BUFFER_CAPACITY);
563        loop {
564            header_line_buffer.clear();
565            AsyncBufReadExt::read_line(reader, &mut header_line_buffer).await?;
566            let header_line: &str = header_line_buffer.trim();
567            if header_line.is_empty() {
568                break;
569            }
570            header_count += 1;
571            Self::check_http_header_count(header_count, max_header_count)?;
572            let (key_part, value_part): (&str, &str) = match header_line.split_once(COLON) {
573                Some(parts) => parts,
574                None => continue,
575            };
576            let key_trimmed: &str = key_part.trim();
577            if key_trimmed.is_empty() {
578                continue;
579            }
580            let key: String = key_trimmed.to_ascii_lowercase();
581            Self::check_http_header_key_size(&key, max_header_key_size)?;
582            let value: &str = value_part.trim();
583            Self::check_http_header_value_size(value, max_header_value_size)?;
584            match key.as_str() {
585                HOST => {
586                    host.clear();
587                    host.push_str(value);
588                }
589                CONTENT_LENGTH => {
590                    content_size = Self::check_http_body_size(value, max_body_size)?;
591                }
592                _ => {}
593            }
594            headers.entry(key).or_default().push_back(value.to_string());
595        }
596        Ok(content_size)
597    }
598
599    /// Reads the request body from the buffered reader into the given buffer.
600    ///
601    /// The target buffer is cleared and resized to the expected content size,
602    /// retaining its allocation when it already has sufficient capacity.
603    ///
604    /// # Arguments
605    ///
606    /// - `&mut R` - The buffered reader to read from, which requires the `AsyncRead + Unpin` bound.
607    /// - `&mut RequestBody` - The buffer to read the body bytes into.
608    /// - `usize` - The expected content size.
609    ///
610    /// # Returns
611    ///
612    /// - `Result<(), RequestError>` - Ok on success, or an error if reading fails.
613    #[inline(always)]
614    pub(crate) async fn fill_http_body<R>(
615        reader: &mut R,
616        body: &mut RequestBody,
617        content_size: usize,
618    ) -> Result<(), RequestError>
619    where
620        R: AsyncRead + Unpin,
621    {
622        body.clear();
623        if content_size > 0 {
624            body.resize(content_size, 0);
625            AsyncReadExt::read_exact(reader, body).await?;
626        }
627        Ok(())
628    }
629
630    /// Tries to get a query parameter value by key.
631    ///
632    /// The key type must implement AsRef<str> conversion.
633    ///
634    /// # Arguments
635    ///
636    /// - `K` - The query parameter key, which implements `AsRef<str>`.
637    ///
638    /// # Returns
639    ///
640    /// - `Option<RequestQuerysValue>` - The parameter value if exists.
641    #[inline(always)]
642    pub fn try_get_query<K>(&self, key: K) -> Option<RequestQuerysValue>
643    where
644        K: AsRef<str>,
645    {
646        self.querys.get(key.as_ref()).cloned()
647    }
648
649    /// Gets a query parameter value by key.
650    ///
651    /// The key type must implement AsRef<str> conversion.
652    ///
653    /// # Arguments
654    ///
655    /// - `K` - The query parameter key, which implements `AsRef<str>`.
656    ///
657    /// # Returns
658    ///
659    /// - `RequestQuerysValue` - The parameter value if exists.
660    ///
661    /// # Panics
662    ///
663    /// This function will panic if the query parameter key is not found.
664    #[inline(always)]
665    pub fn get_query<K>(&self, key: K) -> RequestQuerysValue
666    where
667        K: AsRef<str>,
668    {
669        self.try_get_query(key).unwrap()
670    }
671
672    /// Tries to retrieve the value of a request header by its key.
673    ///
674    /// # Arguments
675    ///
676    /// - `K` - The header's key, which must implement `AsRef<str>`.
677    ///
678    /// # Returns
679    ///
680    /// - `Option<RequestHeadersValue>` - The optional header values.
681    #[inline(always)]
682    pub fn try_get_header<K>(&self, key: K) -> Option<RequestHeadersValue>
683    where
684        K: AsRef<str>,
685    {
686        self.headers.get(key.as_ref()).cloned()
687    }
688
689    /// Retrieves the value of a request header by its key.
690    ///
691    /// # Arguments
692    ///
693    /// - `K` - The header's key, which must implement `AsRef<str>`.
694    ///
695    /// # Returns
696    ///
697    /// - `RequestHeadersValue` - The optional header values.
698    ///
699    /// # Panics
700    ///
701    /// This function will panic if the header key is not found.
702    #[inline(always)]
703    pub fn get_header<K>(&self, key: K) -> RequestHeadersValue
704    where
705        K: AsRef<str>,
706    {
707        self.try_get_header(key).unwrap()
708    }
709
710    /// Tries to retrieve the first value of a request header by its key.
711    ///
712    /// # Arguments
713    ///
714    /// - `K` - The header's key, which must implement `AsRef<str>`.
715    ///
716    /// # Returns
717    ///
718    /// - `Option<RequestHeadersValueItem>` - The first header value if exists.
719    #[inline(always)]
720    pub fn try_get_header_front<K>(&self, key: K) -> Option<RequestHeadersValueItem>
721    where
722        K: AsRef<str>,
723    {
724        self.headers
725            .get(key.as_ref())
726            .and_then(|header_values: &VecDeque<String>| header_values.front().cloned())
727    }
728
729    /// Retrieves the first value of a request header by its key.
730    ///
731    /// # Arguments
732    ///
733    /// - `K` - The header's key, which must implement `AsRef<str>`.
734    ///
735    /// # Returns
736    ///
737    /// - `RequestHeadersValueItem` - The first header value if exists.
738    ///
739    /// # Panics
740    ///
741    /// This function will panic if the header key is not found.
742    #[inline(always)]
743    pub fn get_header_front<K>(&self, key: K) -> RequestHeadersValueItem
744    where
745        K: AsRef<str>,
746    {
747        self.try_get_header_front(key).unwrap()
748    }
749
750    /// Tries to retrieve the last value of a request header by its key.
751    ///
752    /// # Arguments
753    ///
754    /// - `K` - The header's key, which must implement `AsRef<str>`.
755    ///
756    /// # Returns
757    ///
758    /// - `Option<RequestHeadersValueItem>` - The last header value if exists.
759    #[inline(always)]
760    pub fn try_get_header_back<K>(&self, key: K) -> Option<RequestHeadersValueItem>
761    where
762        K: AsRef<str>,
763    {
764        self.headers
765            .get(key.as_ref())
766            .and_then(|header_values: &VecDeque<String>| header_values.back().cloned())
767    }
768
769    /// Retrieves the last value of a request header by its key.
770    ///
771    /// # Arguments
772    ///
773    /// - `K` - The header's key, which must implement `AsRef<str>`.
774    ///
775    /// # Returns
776    ///
777    /// - `RequestHeadersValueItem` - The last header value if exists.
778    ///
779    /// # Panics
780    ///
781    /// This function will panic if the header key is not found.
782    #[inline(always)]
783    pub fn get_header_back<K>(&self, key: K) -> RequestHeadersValueItem
784    where
785        K: AsRef<str>,
786    {
787        self.try_get_header_back(key).unwrap()
788    }
789
790    /// Tries to retrieve the number of values for a specific header.
791    ///
792    /// # Arguments
793    ///
794    /// - `K` - The header's key, which must implement `AsRef<str>`.
795    ///
796    /// # Returns
797    ///
798    /// - `Option<usize>` - The count of values for the header if exists.
799    #[inline(always)]
800    pub fn try_get_header_size<K>(&self, key: K) -> Option<usize>
801    where
802        K: AsRef<str>,
803    {
804        self.headers
805            .get(key.as_ref())
806            .map(|header_values: &VecDeque<String>| header_values.len())
807    }
808
809    /// Retrieves the number of values for a specific header.
810    ///
811    /// # Arguments
812    ///
813    /// - `K` - The header's key, which must implement `AsRef<str>`.
814    ///
815    /// # Returns
816    ///
817    /// - `usize` - The count of values for the header.
818    ///
819    /// # Panics
820    ///
821    /// This function will panic if the header key is not found.
822    #[inline(always)]
823    pub fn get_header_size<K>(&self, key: K) -> usize
824    where
825        K: AsRef<str>,
826    {
827        self.try_get_header_size(key).unwrap()
828    }
829
830    /// Retrieves the total number of header values across all headers.
831    ///
832    /// # Returns
833    ///
834    /// - `usize` - The total count of all header values.
835    #[inline(always)]
836    pub fn get_headers_values_size(&self) -> usize {
837        self.headers
838            .values()
839            .map(|header_values: &VecDeque<String>| header_values.len())
840            .sum()
841    }
842
843    /// Retrieves the number of unique headers.
844    ///
845    /// # Returns
846    ///
847    /// - `usize` - The count of unique header keys.
848    #[inline(always)]
849    pub fn get_headers_size(&self) -> usize {
850        self.headers.len()
851    }
852
853    /// Checks if a specific header exists.
854    ///
855    /// # Arguments
856    ///
857    /// - `K` - The header key to check, which must implement `AsRef<str>`.
858    ///
859    /// # Returns
860    ///
861    /// - `bool` - Whether the header exists.
862    #[inline(always)]
863    pub fn has_header<K>(&self, key: K) -> bool
864    where
865        K: AsRef<str>,
866    {
867        self.get_headers().contains_key(key.as_ref())
868    }
869
870    /// Checks if a header contains a specific value.
871    ///
872    /// # Arguments
873    ///
874    /// - `K` - The header key to check, which must implement `AsRef<str>`.
875    /// - `V` - The value to search for, which must implement `AsRef<str>`.
876    ///
877    /// # Returns
878    ///
879    /// - `bool` - Whether the header contains the value.
880    #[inline(always)]
881    pub fn has_header_value<K, V>(&self, key: K, value: V) -> bool
882    where
883        K: AsRef<str>,
884        V: AsRef<str>,
885    {
886        if let Some(values) = self.get_headers().get(key.as_ref()) {
887            values.iter().any(|data: &String| data == value.as_ref())
888        } else {
889            false
890        }
891    }
892
893    /// Tries to parse cookies from the `Cookie` header.
894    ///
895    /// This method retrieves the `Cookie` header value and parses it into
896    /// a collection of key-value pairs representing the cookies.
897    ///
898    /// # Returns
899    ///
900    /// - `Option<Cookies>` - The parsed cookies if the header exists, otherwise `None`.
901    #[inline(always)]
902    pub fn try_get_cookies(&self) -> Option<Cookies> {
903        self.try_get_header_back(COOKIE)
904            .map(|cookie_header: String| Cookie::parse(cookie_header))
905    }
906
907    /// Parses cookies from the `Cookie` header.
908    ///
909    /// This method retrieves the `Cookie` header value and parses it into
910    /// a collection of key-value pairs representing the cookies.
911    ///
912    /// # Returns
913    ///
914    /// - `Cookies` - The parsed cookies.
915    ///
916    /// # Panics
917    ///
918    /// This function will panic if the `Cookie` header is not found.
919    #[inline(always)]
920    pub fn get_cookies(&self) -> Cookies {
921        self.try_get_cookies().unwrap()
922    }
923
924    /// Tries to get a cookie value by its key.
925    ///
926    /// This method first parses the cookies from the `Cookie` header,
927    /// then attempts to retrieve the value for the specified key.
928    ///
929    /// # Arguments
930    ///
931    /// - `K` - The cookie key, which implements `AsRef<str>`.
932    ///
933    /// # Returns
934    ///
935    /// - `Option<CookieValue>` - The cookie value if exists.
936    #[inline(always)]
937    pub fn try_get_cookie<K>(&self, key: K) -> Option<CookieValue>
938    where
939        K: AsRef<str>,
940    {
941        self.try_get_cookies()
942            .and_then(|cookies: Cookies| cookies.get(key.as_ref()).cloned())
943    }
944
945    /// Gets a cookie value by its key.
946    ///
947    /// This method first parses the cookies from the `Cookie` header,
948    /// then retrieves the value for the specified key.
949    ///
950    /// # Arguments
951    ///
952    /// - `K` - The cookie key, which implements `AsRef<str>`.
953    ///
954    /// # Returns
955    ///
956    /// - `CookieValue` - The cookie value.
957    ///
958    /// # Panics
959    ///
960    /// This function will panic if the `Cookie` header is not found
961    /// or the cookie key does not exist.
962    #[inline(always)]
963    pub fn get_cookie<K>(&self, key: K) -> CookieValue
964    where
965        K: AsRef<str>,
966    {
967        self.try_get_cookie(key).unwrap()
968    }
969
970    /// Retrieves the upgrade type from the request headers.
971    ///
972    /// This method looks for the `UPGRADE` header and attempts to parse its value
973    /// as_ref an `UpgradeType`. If the header is missing or the value is invalid,
974    /// it returns the default `UpgradeType`.
975    ///
976    /// # Returns
977    ///
978    /// - `UpgradeType` - The parsed upgrade type.
979    #[inline(always)]
980    pub fn get_upgrade_type(&self) -> UpgradeType {
981        self.try_get_header_back(UPGRADE)
982            .and_then(|data: String| data.parse::<UpgradeType>().ok())
983            .unwrap_or_default()
984    }
985
986    /// Retrieves the body content of the request as a UTF-8 encoded string.
987    ///
988    /// This method uses `String::from_utf8_lossy` to convert the byte slice returned by `self.get_body()` as a string.
989    /// If the byte slice contains invalid UTF-8 sequences, they will be replaced with the Unicode replacement character ().
990    ///
991    /// # Returns
992    ///
993    /// - `String` - The body content as a string.
994    #[inline(always)]
995    pub fn get_body_string(&self) -> String {
996        String::from_utf8_lossy(self.get_body()).into_owned()
997    }
998
999    /// Deserializes the body content of the request as_ref a specified type `T`.
1000    ///
1001    /// This method first retrieves the body content as a byte slice using `self.get_body()`.
1002    /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
1003    ///
1004    /// The target type `T` is a type parameter of this method and must implement `DeserializeOwned`.
1005    ///
1006    /// # Returns
1007    ///
1008    /// - `Result<T, serde_json::Error>` - The deserialization result.
1009    #[inline(always)]
1010    pub fn try_get_body_json<T>(&self) -> Result<T, serde_json::Error>
1011    where
1012        T: DeserializeOwned,
1013    {
1014        serde_json::from_slice(self.get_body())
1015    }
1016
1017    /// Deserializes the body content of the request as_ref a specified type `T`.
1018    ///
1019    /// This method first retrieves the body content as a byte slice using `self.get_body()`.
1020    /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
1021    ///
1022    /// The target type `T` is a type parameter of this method and must implement `DeserializeOwned`.
1023    ///
1024    /// # Returns
1025    ///
1026    /// - `T` - The deserialized body content.
1027    ///
1028    /// # Panics
1029    ///
1030    /// This function will panic if the deserialization fails.
1031    #[inline(always)]
1032    pub fn get_body_json<T>(&self) -> T
1033    where
1034        T: DeserializeOwned,
1035    {
1036        self.try_get_body_json().unwrap()
1037    }
1038
1039    /// Checks whether the WebSocket upgrade is enabled for this request.
1040    ///
1041    /// This method determines if the `UPGRADE` header indicates a WebSocket connection.
1042    ///
1043    /// # Returns
1044    ///
1045    /// - `bool` - Whether WebSocket upgrade is enabled.
1046    #[inline(always)]
1047    pub fn is_ws_upgrade_type(&self) -> bool {
1048        self.get_upgrade_type().is_ws()
1049    }
1050
1051    /// Checks if the current upgrade type is HTTP/2 cleartext (h2c).
1052    ///
1053    /// # Returns
1054    ///
1055    /// - `bool` - Whether the upgrade type is h2c.
1056    #[inline(always)]
1057    pub fn is_h2c_upgrade_type(&self) -> bool {
1058        self.get_upgrade_type().is_h2c()
1059    }
1060
1061    /// Checks if the current upgrade type is TLS (any version).
1062    ///
1063    /// # Returns
1064    ///
1065    /// - `bool` - Whether the upgrade type is TLS.
1066    #[inline(always)]
1067    pub fn is_tls_upgrade_type(&self) -> bool {
1068        self.get_upgrade_type().is_tls()
1069    }
1070
1071    /// Checks whether the upgrade type is unknown.
1072    ///
1073    /// # Returns
1074    ///
1075    /// - `bool` - Whether the upgrade type is unknown.
1076    #[inline(always)]
1077    pub fn is_unknown_upgrade_type(&self) -> bool {
1078        self.get_upgrade_type().is_unknown()
1079    }
1080
1081    /// Determines if a keep-alive connection should be enabled for this request.
1082    ///
1083    /// This function checks the `Connection` header and the HTTP version to determine
1084    /// if keep-alive should be enabled. The logic is as follows:
1085    ///
1086    /// 1. If the `Connection` header exists:
1087    ///    - Returns `true` if the header value is "keep-alive" (case-insensitive).
1088    ///    - Returns `false` if the header value is "close" (case-insensitive).
1089    /// 2. If no `Connection` header is present:
1090    ///    - Returns `true` if the HTTP version is 1.1 or higher.
1091    ///    - Returns `false` otherwise.
1092    ///
1093    /// # Returns
1094    ///
1095    /// - `bool` - Whether keep-alive should be enabled.
1096    #[inline(always)]
1097    pub fn is_enable_keep_alive(&self) -> bool {
1098        if let Some(connection_value) = self.try_get_header_back(CONNECTION) {
1099            if connection_value.eq_ignore_ascii_case(KEEP_ALIVE) {
1100                return true;
1101            } else if connection_value.eq_ignore_ascii_case(CLOSE) {
1102                return self.is_ws_upgrade_type();
1103            }
1104        }
1105        self.get_version().is_http1_1_or_higher() || self.is_ws_upgrade_type()
1106    }
1107
1108    /// Determines if keep-alive should be disabled for this request.
1109    ///
1110    /// # Returns
1111    ///
1112    /// - `bool` - Whether keep-alive should be disabled.
1113    #[inline(always)]
1114    pub fn is_disable_keep_alive(&self) -> bool {
1115        !self.is_enable_keep_alive()
1116    }
1117}