http_type/request/
impl.rs

1use crate::*;
2
3/// Implements the `std::error::Error` trait for `RequestError`.
4impl std::error::Error for RequestError {}
5
6/// Provides a default value for `RequestError`.
7impl Default for RequestError {
8    /// Provides a default value for `RequestError`.
9    ///
10    /// Returns a `RequestError::Unknown` with `HttpStatus::InternalServerError`.
11    fn default() -> Self {
12        RequestError::Unknown(HttpStatus::InternalServerError)
13    }
14}
15
16impl RequestError {
17    /// Gets the HTTP status associated with this error.
18    ///
19    /// Returns the HttpStatus enum variant that corresponds to this error.
20    ///
21    /// # Arguments
22    ///
23    /// - `&self` - The RequestError instance.
24    ///
25    /// # Returns
26    ///
27    /// - `HttpStatus` - The HTTP status associated with this error.
28    #[inline(always)]
29    pub fn get_http_status(&self) -> HttpStatus {
30        match self {
31            Self::HttpRead(status) => *status,
32            Self::GetTcpStream(status) => *status,
33            Self::GetTlsStream(status) => *status,
34            Self::ReadConnection(status) => *status,
35            Self::RequestAborted(status) => *status,
36            Self::TlsStreamConnect(status) => *status,
37            Self::NeedOpenRedirect(status) => *status,
38            Self::MaxRedirectTimes(status) => *status,
39            Self::MethodsNotSupport(status) => *status,
40            Self::RedirectInvalidUrl(status) => *status,
41            Self::ClientDisconnected(status) => *status,
42            Self::RedirectUrlDeadLoop(status) => *status,
43            Self::ClientClosedConnection(status) => *status,
44            Self::IncompleteWebSocketFrame(status) => *status,
45            Self::RequestTooLong(status) => *status,
46            Self::PathTooLong(status) => *status,
47            Self::QueryTooLong(status) => *status,
48            Self::HeaderLineTooLong(status) => *status,
49            Self::TooManyHeaders(status) => *status,
50            Self::HeaderKeyTooLong(status) => *status,
51            Self::HeaderValueTooLong(status) => *status,
52            Self::ContentLengthTooLarge(status) => *status,
53            Self::InvalidContentLength(status) => *status,
54            Self::InvalidUrlScheme(status) => *status,
55            Self::InvalidUrlHost(status) => *status,
56            Self::InvalidUrlPort(status) => *status,
57            Self::InvalidUrlPath(status) => *status,
58            Self::InvalidUrlQuery(status) => *status,
59            Self::InvalidUrlFragment(status) => *status,
60            Self::ReadTimeout(status) => *status,
61            Self::WriteTimeout(status) => *status,
62            Self::TcpConnectionFailed(status) => *status,
63            Self::TlsHandshakeFailed(status) => *status,
64            Self::TlsCertificateInvalid(status) => *status,
65            Self::WebSocketFrameTooLarge(status) => *status,
66            Self::WebSocketOpcodeUnsupported(status) => *status,
67            Self::WebSocketMaskMissing(status) => *status,
68            Self::WebSocketPayloadCorrupted(status) => *status,
69            Self::WebSocketInvalidUtf8(status) => *status,
70            Self::WebSocketInvalidCloseCode(status) => *status,
71            Self::WebSocketInvalidExtension(status) => *status,
72            Self::HttpRequestPartsInsufficient(status) => *status,
73            Self::TcpStreamConnect(status) => *status,
74            Self::TlsConnectorBuild(status) => *status,
75            Self::InvalidUrl(status) => *status,
76            Self::ConfigReadError(status) => *status,
77            Self::TcpStreamConnectString(status) => *status,
78            Self::TlsConnectorBuildString(status) => *status,
79            Self::Request(_) => HttpStatus::BadRequest,
80            Self::Unknown(status) => *status,
81        }
82    }
83
84    /// Gets the numeric HTTP status code associated with this error.
85    ///
86    /// Returns the numeric status code (e.g., 400, 404, 500) that corresponds to this error.
87    ///
88    /// # Arguments
89    ///
90    /// - `&self` - The RequestError instance.
91    ///
92    /// # Returns
93    ///
94    /// - `ResponseStatusCode` - The numeric HTTP status code.
95    pub fn get_http_status_code(&self) -> ResponseStatusCode {
96        self.get_http_status().code()
97    }
98}
99
100impl Default for RequestConfig {
101    /// Creates a `RequestConfig` with secure default values.
102    ///
103    /// # Returns
104    ///
105    /// - `RequestConfig` - A new config instance with secure defaults.
106    #[inline(always)]
107    fn default() -> Self {
108        Self {
109            buffer_size: DEFAULT_BUFFER_SIZE,
110            max_request_line_length: DEFAULT_MAX_REQUEST_LINE_LENGTH,
111            max_path_length: DEFAULT_MAX_PATH_LENGTH,
112            max_query_length: DEFAULT_MAX_QUERY_LENGTH,
113            max_header_line_length: DEFAULT_MAX_HEADER_LINE_LENGTH,
114            max_header_count: DEFAULT_MAX_HEADER_COUNT,
115            max_header_key_length: DEFAULT_MAX_HEADER_KEY_LENGTH,
116            max_header_value_length: DEFAULT_MAX_HEADER_VALUE_LENGTH,
117            max_body_size: DEFAULT_MAX_BODY_SIZE,
118            max_ws_frame_size: DEFAULT_MAX_WS_FRAME_SIZE,
119            max_ws_frames: DEFAULT_MAX_WS_FRAMES,
120            http_read_timeout_ms: DEFAULT_HTTP_READ_TIMEOUT_MS,
121            ws_read_timeout_ms: DEFAULT_WS_READ_TIMEOUT_MS,
122        }
123    }
124}
125
126impl RequestConfig {
127    /// Creates a new `RequestConfig` with default values.
128    ///
129    /// # Returns
130    ///
131    /// - `RequestConfig` - A new config instance with default values.
132    #[inline(always)]
133    pub fn new() -> Self {
134        Self::default()
135    }
136
137    /// Creates a config optimized for high-security environments.
138    ///
139    /// This configuration uses more restrictive limits to provide
140    /// maximum protection against various attacks.
141    ///
142    /// # Returns
143    ///
144    /// - `RequestConfig` - A new config with high-security settings.
145    #[inline(always)]
146    pub fn high_security() -> Self {
147        Self {
148            buffer_size: DEFAULT_HIGH_SECURITY_BUFFER_SIZE,
149            max_request_line_length: DEFAULT_HIGH_SECURITY_MAX_REQUEST_LINE_LENGTH,
150            max_path_length: DEFAULT_HIGH_SECURITY_MAX_PATH_LENGTH,
151            max_query_length: DEFAULT_HIGH_SECURITY_MAX_QUERY_LENGTH,
152            max_header_line_length: DEFAULT_HIGH_SECURITY_MAX_HEADER_LINE_LENGTH,
153            max_header_count: DEFAULT_HIGH_SECURITY_MAX_HEADER_COUNT,
154            max_header_key_length: DEFAULT_HIGH_SECURITY_MAX_HEADER_KEY_LENGTH,
155            max_header_value_length: DEFAULT_HIGH_SECURITY_MAX_HEADER_VALUE_LENGTH,
156            max_body_size: DEFAULT_HIGH_SECURITY_MAX_BODY_SIZE,
157            max_ws_frame_size: DEFAULT_HIGH_SECURITY_MAX_WS_FRAME_SIZE,
158            max_ws_frames: DEFAULT_HIGH_SECURITY_MAX_WS_FRAMES,
159            http_read_timeout_ms: DEFAULT_HIGH_SECURITY_HTTP_READ_TIMEOUT_MS,
160            ws_read_timeout_ms: DEFAULT_HIGH_SECURITY_WS_READ_TIMEOUT_MS,
161        }
162    }
163}
164
165/// Provides a default value for `Request`.
166///
167/// Returns a new `Request` instance with all fields initialized to their default values.
168impl Default for Request {
169    #[inline(always)]
170    fn default() -> Self {
171        Self {
172            method: Method::default(),
173            host: String::new(),
174            version: HttpVersion::default(),
175            path: String::new(),
176            querys: hash_map_xx_hash3_64(),
177            headers: hash_map_xx_hash3_64(),
178            body: Vec::new(),
179        }
180    }
181}
182
183impl Request {
184    /// Creates a new instance of `Request`.
185    ///
186    /// # Returns
187    ///
188    /// - `Request` - A new request instance with default values.
189    #[inline(always)]
190    pub fn new() -> Self {
191        Self::default()
192    }
193
194    /// Parses a query string as_ref key-value pairs.
195    ///
196    /// Expects format "key1=value1&key2=value2". Empty values are allowed.
197    ///
198    /// # Arguments
199    ///
200    /// - `&str` - The query string to parse.
201    ///
202    /// # Returns
203    ///
204    /// - `HashMap<String, String>` - The parsed query parameters.
205    fn parse_querys<Q>(query: Q) -> RequestQuerys
206    where
207        Q: AsRef<str>,
208    {
209        let mut query_map: RequestQuerys = hash_map_xx_hash3_64();
210        for pair in query.as_ref().split(AND) {
211            if let Some((key, value)) = pair.split_once(EQUAL) {
212                if !key.is_empty() {
213                    query_map.insert(key.to_string(), value.to_string());
214                }
215            } else if !pair.is_empty() {
216                query_map.insert(pair.to_string(), String::new());
217            }
218        }
219        query_map
220    }
221
222    /// Parses HTTP headers from a buffered reader.
223    ///
224    /// This method reads header lines from the provided buffered reader until an empty line
225    /// is encountered, which indicates the end of headers. It validates header count, length,
226    /// and content according to the provided configuration.
227    ///
228    /// # Arguments
229    ///
230    /// - `&mut R` - A mutable reference to a buffered reader implementing `AsyncBufReadExt`.
231    /// - `&RequestConfig` - Configuration for security limits and buffer settings.
232    ///
233    /// # Returns
234    ///
235    /// - `Result<(RequestHeaders, RequestHost, usize), RequestError>` - A tuple containing:
236    ///   - The parsed headers as a hash map
237    ///   - The host value extracted from the Host header
238    ///   - The content length extracted from the Content-Length header
239    ///   - Or an error if parsing fails
240    async fn parse_headers<R>(
241        reader: &mut R,
242        config: &RequestConfig,
243    ) -> Result<(RequestHeaders, RequestHost, usize), RequestError>
244    where
245        R: AsyncBufReadExt + Unpin,
246    {
247        let buffer_size: usize = *config.get_buffer_size();
248        let mut headers: RequestHeaders = hash_map_xx_hash3_64();
249        let mut host: RequestHost = String::new();
250        let mut content_length: usize = 0;
251        let mut header_count: usize = 0;
252        loop {
253            let header_line: &mut String = &mut String::with_capacity(buffer_size);
254            let bytes_read: usize = AsyncBufReadExt::read_line(reader, header_line)
255                .await
256                .map_err(|_| RequestError::HttpRead(HttpStatus::BadRequest))?;
257            if bytes_read > config.max_header_line_length {
258                return Err(RequestError::HeaderLineTooLong(
259                    HttpStatus::RequestHeaderFieldsTooLarge,
260                ));
261            }
262            let header_line: &str = header_line.trim();
263            if header_line.is_empty() {
264                break;
265            }
266            header_count += 1;
267            if header_count > config.max_header_count {
268                return Err(RequestError::TooManyHeaders(
269                    HttpStatus::RequestHeaderFieldsTooLarge,
270                ));
271            }
272            if let Some((key_part, value_part)) = header_line.split_once(COLON) {
273                let key: String = key_part.trim().to_ascii_lowercase();
274                if key.is_empty() {
275                    continue;
276                }
277                if key.len() > config.max_header_key_length {
278                    return Err(RequestError::HeaderKeyTooLong(
279                        HttpStatus::RequestHeaderFieldsTooLarge,
280                    ));
281                }
282                let value: String = value_part.trim().to_string();
283                if value.len() > config.max_header_value_length {
284                    return Err(RequestError::HeaderValueTooLong(
285                        HttpStatus::RequestHeaderFieldsTooLarge,
286                    ));
287                }
288                if key == HOST {
289                    host = value.clone();
290                } else if key == CONTENT_LENGTH {
291                    match value.parse::<usize>() {
292                        Ok(length) => {
293                            if length > config.max_body_size {
294                                return Err(RequestError::ContentLengthTooLarge(
295                                    HttpStatus::PayloadTooLarge,
296                                ));
297                            }
298                            content_length = length;
299                        }
300                        Err(_) => {
301                            return Err(RequestError::InvalidContentLength(HttpStatus::BadRequest));
302                        }
303                    }
304                }
305                headers.entry(key).or_default().push_back(value);
306            }
307        }
308        Ok((headers, host, content_length))
309    }
310
311    /// Parses an HTTP request from a TCP stream.
312    ///
313    /// Wraps the stream in a buffered reader and delegates to `http_from_reader`.
314    ///
315    /// # Arguments
316    ///
317    /// - `&ArcRwLock<TcpStream>` - The TCP stream to read from.
318    /// - `&RequestConfig` - Configuration for security limits and buffer settings.
319    ///
320    /// # Returns
321    ///
322    /// - `Result<Request, RequestError>` - The parsed request or an error.
323    pub async fn http_from_stream(
324        stream: &ArcRwLockStream,
325        config: &RequestConfig,
326    ) -> Result<Request, RequestError> {
327        timeout(
328            Duration::from_millis(config.http_read_timeout_ms),
329            async move {
330                let mut buf_stream: RwLockWriteGuard<'_, TcpStream> = stream.write().await;
331                let buffer_size: usize = *config.get_buffer_size();
332                let reader: &mut BufReader<&mut TcpStream> =
333                    &mut BufReader::with_capacity(buffer_size, &mut buf_stream);
334                let mut request_line: String = String::with_capacity(buffer_size);
335                let bytes_read: usize = AsyncBufReadExt::read_line(reader, &mut request_line)
336                    .await
337                    .map_err(|_| RequestError::HttpRead(HttpStatus::BadRequest))?;
338                if bytes_read > config.max_request_line_length {
339                    return Err(RequestError::RequestTooLong(HttpStatus::BadRequest));
340                }
341                let parts: Vec<&str> = request_line.split_whitespace().collect();
342                let parts_len: usize = parts.len();
343                if parts_len < 3 {
344                    return Err(RequestError::HttpRequestPartsInsufficient(
345                        HttpStatus::BadRequest,
346                    ));
347                }
348                let method: RequestMethod = parts[0]
349                    .parse::<RequestMethod>()
350                    .unwrap_or(Method::Unknown(parts[0].to_string()));
351                let full_path: &str = parts[1];
352                if full_path.len() > config.max_path_length {
353                    return Err(RequestError::PathTooLong(HttpStatus::URITooLong));
354                }
355                let full_path: RequestPath = full_path.to_string();
356                let version: RequestVersion = parts[2]
357                    .parse::<RequestVersion>()
358                    .unwrap_or(RequestVersion::Unknown(parts[2].to_string()));
359                let hash_index: Option<usize> = full_path.find(HASH);
360                let query_index: Option<usize> = full_path.find(QUERY);
361                let query_string: String = query_index.map_or_else(String::new, |i| {
362                    let temp: &str = &full_path[i + 1..];
363                    if hash_index.is_none() || hash_index.unwrap() <= i {
364                        return temp.to_owned();
365                    }
366                    temp.split(HASH).next().unwrap_or_default().to_owned()
367                });
368                if query_string.len() > config.max_query_length {
369                    return Err(RequestError::QueryTooLong(HttpStatus::URITooLong));
370                }
371                let querys: RequestQuerys = Self::parse_querys(&query_string);
372                let path: RequestPath = if let Some(i) = query_index.or(hash_index) {
373                    full_path[..i].to_owned()
374                } else {
375                    full_path.to_owned()
376                };
377                let (headers, host, content_length): (RequestHeaders, RequestHost, usize) =
378                    Self::parse_headers(reader, config).await?;
379                let mut body: RequestBody = Vec::with_capacity(content_length);
380                if content_length > 0 {
381                    body.resize(content_length, 0);
382                    AsyncReadExt::read_exact(reader, &mut body)
383                        .await
384                        .map_err(|_| RequestError::ReadConnection(HttpStatus::BadRequest))?;
385                }
386                Ok(Request {
387                    method,
388                    host,
389                    version,
390                    path,
391                    querys,
392                    headers,
393                    body,
394                })
395            },
396        )
397        .await
398        .map_err(|_| RequestError::ReadTimeout(HttpStatus::RequestTimeout))?
399    }
400
401    /// Parses a WebSocket request from a TCP stream.
402    ///
403    /// Wraps the stream in a buffered reader and delegates to `ws_from_reader`.
404    ///
405    /// # Arguments
406    ///
407    /// - `&ArcRwLock<TcpStream>` - The TCP stream to read from.
408    /// - `&RequestConfig` - Configuration for security limits and buffer settings.
409    ///
410    /// # Returns
411    ///
412    /// - `Result<Request, RequestError>` - The parsed WebSocket request or an error.
413    pub async fn ws_from_stream(
414        &mut self,
415        stream: &ArcRwLockStream,
416        config: &RequestConfig,
417    ) -> Result<Request, RequestError> {
418        let buffer_size: usize = *config.get_buffer_size();
419        let mut dynamic_buffer: Vec<u8> = Vec::with_capacity(buffer_size);
420        let temp_buffer_size: usize = buffer_size;
421        let mut temp_buffer: Vec<u8> = vec![0; temp_buffer_size];
422        let mut full_frame: Vec<u8> = Vec::with_capacity(config.max_ws_frame_size);
423        let mut frame_count: usize = 0;
424        let mut is_client_response: bool = false;
425        let ws_read_timeout_ms: u64 =
426            (config.ws_read_timeout_ms >> 1) + (config.ws_read_timeout_ms & 1);
427        let timeout_duration: Duration = Duration::from_millis(ws_read_timeout_ms);
428        loop {
429            let len: usize = match timeout(
430                timeout_duration,
431                stream.write().await.read(&mut temp_buffer),
432            )
433            .await
434            {
435                Ok(result) => match result {
436                    Ok(len) => len,
437                    Err(error) => {
438                        if error.kind() == ErrorKind::ConnectionReset
439                            || error.kind() == ErrorKind::ConnectionAborted
440                        {
441                            return Err(RequestError::ClientDisconnected(HttpStatus::BadRequest));
442                        }
443                        return Err(RequestError::Unknown(HttpStatus::InternalServerError));
444                    }
445                },
446                Err(_) => {
447                    if !is_client_response {
448                        return Err(RequestError::ReadTimeout(HttpStatus::RequestTimeout));
449                    }
450                    is_client_response = false;
451                    stream
452                        .try_send_body(&PING_FRAME)
453                        .await
454                        .map_err(|_| RequestError::WriteTimeout(HttpStatus::InternalServerError))?;
455                    let _ = stream.try_flush().await;
456                    continue;
457                }
458            };
459            if len == 0 {
460                return Err(RequestError::IncompleteWebSocketFrame(
461                    HttpStatus::BadRequest,
462                ));
463            }
464            dynamic_buffer.extend_from_slice(&temp_buffer[..len]);
465            while let Some((frame, consumed)) = WebSocketFrame::decode_ws_frame(&dynamic_buffer) {
466                is_client_response = true;
467                dynamic_buffer.drain(0..consumed);
468                frame_count += 1;
469                if frame_count > config.max_ws_frames {
470                    return Err(RequestError::TooManyHeaders(
471                        HttpStatus::RequestHeaderFieldsTooLarge,
472                    ));
473                }
474                match frame.get_opcode() {
475                    WebSocketOpcode::Close => {
476                        return Err(RequestError::ClientClosedConnection(HttpStatus::BadRequest));
477                    }
478                    WebSocketOpcode::Ping | WebSocketOpcode::Pong => {
479                        continue;
480                    }
481                    WebSocketOpcode::Text | WebSocketOpcode::Binary => {
482                        let payload_data: &[u8] = frame.get_payload_data();
483                        if payload_data.len() > config.max_ws_frame_size {
484                            return Err(RequestError::WebSocketFrameTooLarge(
485                                HttpStatus::PayloadTooLarge,
486                            ));
487                        }
488                        if full_frame.len() + payload_data.len() > config.max_ws_frame_size {
489                            return Err(RequestError::WebSocketFrameTooLarge(
490                                HttpStatus::PayloadTooLarge,
491                            ));
492                        }
493                        full_frame.extend_from_slice(payload_data);
494                        if *frame.get_fin() {
495                            let mut request: Request = self.clone();
496                            request.body = full_frame;
497                            return Ok(request);
498                        }
499                    }
500                    _ => {
501                        return Err(RequestError::WebSocketOpcodeUnsupported(
502                            HttpStatus::NotImplemented,
503                        ));
504                    }
505                }
506            }
507        }
508    }
509
510    /// Tries to get a query parameter value by key.
511    ///
512    /// The key type must implement AsRef<str> conversion.
513    ///
514    /// # Arguments
515    ///
516    /// - `AsRef<str>` - The query parameter key (implements AsRef<str>).
517    ///
518    /// # Returns
519    ///
520    /// - `Option<RequestQuerysValue>` - The parameter value if exists.
521    #[inline(always)]
522    pub fn try_get_query<K>(&self, key: K) -> Option<RequestQuerysValue>
523    where
524        K: AsRef<str>,
525    {
526        self.querys.get(key.as_ref()).cloned()
527    }
528
529    /// Gets a query parameter value by key.
530    ///
531    /// The key type must implement AsRef<str> conversion.
532    ///
533    /// # Arguments
534    ///
535    /// - `AsRef<str>` - The query parameter key (implements AsRef<str>).
536    ///
537    /// # Returns
538    ///
539    /// - `RequestQuerysValue` - The parameter value if exists.
540    ///
541    /// # Panics
542    ///
543    /// This function will panic if the query parameter key is not found.
544    #[inline(always)]
545    pub fn get_query<K>(&self, key: K) -> RequestQuerysValue
546    where
547        K: AsRef<str>,
548    {
549        self.try_get_query(key).unwrap()
550    }
551
552    /// Tries to retrieve the value of a request header by its key.
553    ///
554    /// # Arguments
555    ///
556    /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
557    ///
558    /// # Returns
559    ///
560    /// - `Option<RequestHeadersValue>` - The optional header values.
561    #[inline(always)]
562    pub fn try_get_header<K>(&self, key: K) -> Option<RequestHeadersValue>
563    where
564        K: AsRef<str>,
565    {
566        self.headers.get(key.as_ref()).cloned()
567    }
568
569    /// Retrieves the value of a request header by its key.
570    ///
571    /// # Arguments
572    ///
573    /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
574    ///
575    /// # Returns
576    ///
577    /// - `RequestHeadersValue` - The optional header values.
578    ///
579    /// # Panics
580    ///
581    /// This function will panic if the header key is not found.
582    #[inline(always)]
583    pub fn get_header<K>(&self, key: K) -> RequestHeadersValue
584    where
585        K: AsRef<str>,
586    {
587        self.try_get_header(key).unwrap()
588    }
589
590    /// Tries to retrieve the first value of a request header by its key.
591    ///
592    /// # Arguments
593    ///
594    /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
595    ///
596    /// # Returns
597    ///
598    /// - `Option<RequestHeadersValueItem>` - The first header value if exists.
599    #[inline(always)]
600    pub fn try_get_header_front<K>(&self, key: K) -> Option<RequestHeadersValueItem>
601    where
602        K: AsRef<str>,
603    {
604        self.headers
605            .get(key.as_ref())
606            .and_then(|values| values.front().cloned())
607    }
608
609    /// Retrieves the first value of a request header by its key.
610    ///
611    /// # Arguments
612    ///
613    /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
614    ///
615    /// # Returns
616    ///
617    /// - `RequestHeadersValueItem` - The first header value if exists.
618    ///
619    /// # Panics
620    ///
621    /// This function will panic if the header key is not found.
622    #[inline(always)]
623    pub fn get_header_front<K>(&self, key: K) -> RequestHeadersValueItem
624    where
625        K: AsRef<str>,
626    {
627        self.try_get_header_front(key).unwrap()
628    }
629
630    /// Tries to retrieve the last value of a request header by its key.
631    ///
632    /// # Arguments
633    ///
634    /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
635    ///
636    /// # Returns
637    ///
638    /// - `Option<RequestHeadersValueItem>` - The last header value if exists.
639    #[inline(always)]
640    pub fn try_get_header_back<K>(&self, key: K) -> Option<RequestHeadersValueItem>
641    where
642        K: AsRef<str>,
643    {
644        self.headers
645            .get(key.as_ref())
646            .and_then(|values| values.back().cloned())
647    }
648
649    /// Retrieves the last value of a request header by its key.
650    ///
651    /// # Arguments
652    ///
653    /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
654    ///
655    /// # Returns
656    ///
657    /// - `RequestHeadersValueItem` - The last header value if exists.
658    ///
659    /// # Panics
660    ///
661    /// This function will panic if the header key is not found.
662    #[inline(always)]
663    pub fn get_header_back<K>(&self, key: K) -> RequestHeadersValueItem
664    where
665        K: AsRef<str>,
666    {
667        self.try_get_header_back(key).unwrap()
668    }
669
670    /// Tries to retrieve the number of values for a specific header.
671    ///
672    /// # Arguments
673    ///
674    /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
675    ///
676    /// # Returns
677    ///
678    /// - `Option<usize>` - The count of values for the header if exists.
679    #[inline(always)]
680    pub fn try_get_header_length<K>(&self, key: K) -> Option<usize>
681    where
682        K: AsRef<str>,
683    {
684        self.headers.get(key.as_ref()).map(|values| values.len())
685    }
686
687    /// Retrieves the number of values for a specific header.
688    ///
689    /// # Arguments
690    ///
691    /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
692    ///
693    /// # Returns
694    ///
695    /// - `usize` - The count of values for the header.
696    ///
697    /// # Panics
698    ///
699    /// This function will panic if the header key is not found.
700    #[inline(always)]
701    pub fn get_header_length<K>(&self, key: K) -> usize
702    where
703        K: AsRef<str>,
704    {
705        self.try_get_header_length(key).unwrap()
706    }
707
708    /// Retrieves the total number of header values across all headers.
709    ///
710    /// # Returns
711    ///
712    /// - `usize` - The total count of all header values.
713    #[inline(always)]
714    pub fn get_headers_values_length(&self) -> usize {
715        self.headers.values().map(|values| values.len()).sum()
716    }
717
718    /// Retrieves the number of unique headers.
719    ///
720    /// # Returns
721    ///
722    /// - `usize` - The count of unique header keys.
723    #[inline(always)]
724    pub fn get_headers_length(&self) -> usize {
725        self.headers.len()
726    }
727
728    /// Checks if a specific header exists.
729    ///
730    /// # Arguments
731    ///
732    /// - `AsRef<str>` - The header key to check (must implement AsRef<str>).
733    ///
734    /// # Returns
735    ///
736    /// - `bool` - Whether the header exists.
737    #[inline(always)]
738    pub fn has_header<K>(&self, key: K) -> bool
739    where
740        K: AsRef<str>,
741    {
742        self.headers.contains_key(key.as_ref())
743    }
744
745    /// Checks if a header contains a specific value.
746    ///
747    /// # Arguments
748    ///
749    /// - `AsRef<str>` - The header key to check (must implement AsRef<str>).
750    /// - `AsRef<str>` - The value to search for (must implement AsRef<str>).
751    ///
752    /// # Returns
753    ///
754    /// - `bool` - Whether the header contains the value.
755    #[inline(always)]
756    pub fn has_header_value<K, V>(&self, key: K, value: V) -> bool
757    where
758        K: AsRef<str>,
759        V: AsRef<str>,
760    {
761        if let Some(values) = self.headers.get(key.as_ref()) {
762            values.contains(&value.as_ref().to_owned())
763        } else {
764            false
765        }
766    }
767
768    /// Retrieves the body content of the request as a UTF-8 encoded string.
769    ///
770    /// This method uses `String::from_utf8_lossy` to convert the byte slice returned by `self.get_body()` as_ref a string.
771    /// If the byte slice contains invalid UTF-8 sequences, they will be replaced with the Unicode replacement character ().
772    ///
773    /// # Returns
774    ///
775    /// - `String` - The body content as a string.
776    #[inline(always)]
777    pub fn get_body_string(&self) -> String {
778        String::from_utf8_lossy(self.get_body()).into_owned()
779    }
780
781    /// Deserializes the body content of the request as_ref a specified type `T`.
782    ///
783    /// This method first retrieves the body content as a byte slice using `self.get_body()`.
784    /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
785    ///
786    /// # Arguments
787    ///
788    /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
789    ///
790    /// # Returns
791    ///
792    /// - `Result<T, serde_json::Error>` - The deserialization result.
793    pub fn try_get_body_json<T>(&self) -> Result<T, serde_json::Error>
794    where
795        T: DeserializeOwned,
796    {
797        serde_json::from_slice(self.get_body())
798    }
799
800    /// Deserializes the body content of the request as_ref a specified type `T`.
801    ///
802    /// This method first retrieves the body content as a byte slice using `self.get_body()`.
803    /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
804    ///
805    /// # Arguments
806    ///
807    /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
808    ///
809    /// # Returns
810    ///
811    /// - `T` - The deserialized body content.
812    ///
813    /// # Panics
814    ///
815    /// This function will panic if the deserialization fails.
816    pub fn get_body_json<T>(&self) -> T
817    where
818        T: DeserializeOwned,
819    {
820        self.try_get_body_json().unwrap()
821    }
822
823    /// Converts the request to a formatted string representation.
824    ///
825    /// This method provides a human-readable summary of the request, including its method,
826    /// host, version, path, query parameters, headers, and body information.
827    ///
828    /// # Returns
829    ///
830    /// - `String` - The formatted request details.
831    #[inline(always)]
832    pub fn get_string(&self) -> String {
833        let body: &Vec<u8> = self.get_body();
834        let body_type: &'static str = if std::str::from_utf8(body).is_ok() {
835            PLAIN
836        } else {
837            BINARY
838        };
839        format!(
840            "[Request] => [method]: {}; [host]: {}; [version]: {}; [path]: {}; [querys]: {:?}; [headers]: {:?}; [body]: {} bytes {};",
841            self.get_method(),
842            self.get_host(),
843            self.get_version(),
844            self.get_path(),
845            self.get_querys(),
846            self.get_headers(),
847            body.len(),
848            body_type
849        )
850    }
851
852    /// Retrieves the upgrade type from the request headers.
853    ///
854    /// This method looks for the `UPGRADE` header and attempts to parse its value
855    /// as_ref an `UpgradeType`. If the header is missing or the value is invalid,
856    /// it returns the default `UpgradeType`.
857    ///
858    /// # Returns
859    ///
860    /// - `UpgradeType` - The parsed upgrade type.
861    #[inline(always)]
862    pub fn get_upgrade_type(&self) -> UpgradeType {
863        let upgrade_type: UpgradeType = self
864            .try_get_header_back(UPGRADE)
865            .and_then(|data| data.parse::<UpgradeType>().ok())
866            .unwrap_or_default();
867        upgrade_type
868    }
869
870    /// Checks whether the WebSocket upgrade is enabled for this request.
871    ///
872    /// This method determines if the `UPGRADE` header indicates a WebSocket connection.
873    ///
874    /// # Returns
875    ///
876    /// - `bool` - Whether WebSocket upgrade is enabled.
877    #[inline(always)]
878    pub fn is_ws(&self) -> bool {
879        self.get_upgrade_type().is_ws()
880    }
881
882    /// Checks if the current upgrade type is HTTP/2 cleartext (h2c).
883    ///
884    /// # Returns
885    ///
886    /// - `bool` - Whether the upgrade type is h2c.
887    #[inline(always)]
888    pub fn is_h2c(&self) -> bool {
889        self.get_upgrade_type().is_h2c()
890    }
891
892    /// Checks if the current upgrade type is TLS (any version).
893    ///
894    /// # Returns
895    ///
896    /// - `bool` - Whether the upgrade type is TLS.
897    #[inline(always)]
898    pub fn is_tls(&self) -> bool {
899        self.get_upgrade_type().is_tls()
900    }
901
902    /// Checks whether the upgrade type is unknown.
903    ///
904    /// # Returns
905    ///
906    /// - `bool` - Whether the upgrade type is unknown.
907    #[inline(always)]
908    pub fn is_unknown_upgrade(&self) -> bool {
909        self.get_upgrade_type().is_unknown()
910    }
911
912    /// Checks if the HTTP version is HTTP/1.1 or higher.
913    ///
914    /// # Returns
915    ///
916    /// - `bool` - Whether the version is HTTP/1.1 or higher.
917    #[inline(always)]
918    pub fn is_http1_1_or_higher(&self) -> bool {
919        self.get_version().is_http1_1_or_higher()
920    }
921
922    /// Checks whether the HTTP version is HTTP/0.9.
923    ///
924    /// # Returns
925    ///
926    /// - `bool` - Whether the version is HTTP/0.9.
927    #[inline(always)]
928    pub fn is_http0_9(&self) -> bool {
929        self.get_version().is_http0_9()
930    }
931
932    /// Checks whether the HTTP version is HTTP/1.0.
933    ///
934    /// # Returns
935    ///
936    /// - `bool` - Whether the version is HTTP/1.0.
937    #[inline(always)]
938    pub fn is_http1_0(&self) -> bool {
939        self.get_version().is_http1_0()
940    }
941
942    /// Checks whether the HTTP version is HTTP/1.1.
943    ///
944    /// # Returns
945    ///
946    /// - `bool` - Whether the version is HTTP/1.1.
947    #[inline(always)]
948    pub fn is_http1_1(&self) -> bool {
949        self.get_version().is_http1_1()
950    }
951
952    /// Checks whether the HTTP version is HTTP/2.
953    ///
954    /// # Returns
955    ///
956    /// - `bool` - Whether the version is HTTP/2.
957    #[inline(always)]
958    pub fn is_http2(&self) -> bool {
959        self.get_version().is_http2()
960    }
961
962    /// Checks whether the HTTP version is HTTP/3.
963    ///
964    /// # Returns
965    ///
966    /// - `bool` - Whether the version is HTTP/3.
967    #[inline(always)]
968    pub fn is_http3(&self) -> bool {
969        self.get_version().is_http3()
970    }
971
972    /// Checks whether the HTTP version is unknown.
973    ///
974    /// # Returns
975    ///
976    /// - `bool` - Whether the version is unknown.
977    #[inline(always)]
978    pub fn is_unknown_version(&self) -> bool {
979        self.get_version().is_unknown()
980    }
981
982    /// Checks whether the version belongs to the HTTP family.
983    ///
984    /// # Returns
985    ///
986    /// - `bool` - Whether the version is HTTP.
987    #[inline(always)]
988    pub fn is_http(&self) -> bool {
989        self.get_version().is_http()
990    }
991
992    /// Checks whether the request method is GET.
993    ///
994    /// # Returns
995    ///
996    /// - `bool` - Whether the method is GET.
997    #[inline(always)]
998    pub fn is_get(&self) -> bool {
999        self.get_method().is_get()
1000    }
1001
1002    /// Checks whether the request method is POST.
1003    ///
1004    /// # Returns
1005    ///
1006    /// - `bool` - Whether the method is POST.
1007    #[inline(always)]
1008    pub fn is_post(&self) -> bool {
1009        self.get_method().is_post()
1010    }
1011
1012    /// Checks whether the request method is PUT.
1013    ///
1014    /// # Returns
1015    ///
1016    /// - `bool` - Whether the method is PUT.
1017    #[inline(always)]
1018    pub fn is_put(&self) -> bool {
1019        self.get_method().is_put()
1020    }
1021
1022    /// Checks whether the request method is DELETE.
1023    ///
1024    /// # Returns
1025    ///
1026    /// - `bool` - Whether the method is DELETE.
1027    #[inline(always)]
1028    pub fn is_delete(&self) -> bool {
1029        self.get_method().is_delete()
1030    }
1031
1032    /// Checks whether the request method is PATCH.
1033    ///
1034    /// # Returns
1035    ///
1036    /// - `bool` - Whether the method is PATCH.
1037    #[inline(always)]
1038    pub fn is_patch(&self) -> bool {
1039        self.get_method().is_patch()
1040    }
1041
1042    /// Checks whether the request method is HEAD.
1043    ///
1044    /// # Returns
1045    ///
1046    /// - `bool` - Whether the method is HEAD.
1047    #[inline(always)]
1048    pub fn is_head(&self) -> bool {
1049        self.get_method().is_head()
1050    }
1051
1052    /// Checks whether the request method is OPTIONS.
1053    ///
1054    /// # Returns
1055    ///
1056    /// - `bool` - Whether the method is OPTIONS.
1057    #[inline(always)]
1058    pub fn is_options(&self) -> bool {
1059        self.get_method().is_options()
1060    }
1061
1062    /// Checks whether the request method is CONNECT.
1063    ///
1064    /// # Returns
1065    ///
1066    /// - `bool` - Whether the method is CONNECT.
1067    #[inline(always)]
1068    pub fn is_connect(&self) -> bool {
1069        self.get_method().is_connect()
1070    }
1071
1072    /// Checks whether the request method is TRACE.
1073    ///
1074    /// # Returns
1075    ///
1076    /// - `bool` - Whether the method is TRACE.
1077    #[inline(always)]
1078    pub fn is_trace(&self) -> bool {
1079        self.get_method().is_trace()
1080    }
1081
1082    /// Checks whether the request method is UNKNOWN.
1083    ///
1084    /// # Returns
1085    ///
1086    /// - `bool` - Whether the method is UNKNOWN.
1087    #[inline(always)]
1088    pub fn is_unknown_method(&self) -> bool {
1089        self.get_method().is_unknown()
1090    }
1091
1092    /// Determines if a keep-alive connection should be enabled for this request.
1093    ///
1094    /// This function checks the `Connection` header and the HTTP version to determine
1095    /// if keep-alive should be enabled. The logic is as follows:
1096    ///
1097    /// 1. If the `Connection` header exists:
1098    ///    - Returns `true` if the header value is "keep-alive" (case-insensitive).
1099    ///    - Returns `false` if the header value is "close" (case-insensitive).
1100    /// 2. If no `Connection` header is present:
1101    ///    - Returns `true` if the HTTP version is 1.1 or higher.
1102    ///    - Returns `false` otherwise.
1103    ///
1104    /// # Returns
1105    ///
1106    /// - `bool` - Whether keep-alive should be enabled.
1107    #[inline(always)]
1108    pub fn is_enable_keep_alive(&self) -> bool {
1109        if let Some(connection_value) = self.try_get_header_back(CONNECTION) {
1110            if connection_value.eq_ignore_ascii_case(KEEP_ALIVE) {
1111                return true;
1112            } else if connection_value.eq_ignore_ascii_case(CLOSE) {
1113                return self.is_ws();
1114            }
1115        }
1116        self.is_http1_1_or_higher() || self.is_ws()
1117    }
1118
1119    /// Determines if keep-alive should be disabled for this request.
1120    ///
1121    /// # Returns
1122    ///
1123    /// - `bool` - Whether keep-alive should be disabled.
1124    #[inline(always)]
1125    pub fn is_disable_keep_alive(&self) -> bool {
1126        !self.is_enable_keep_alive()
1127    }
1128}