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