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