http_type/request/
impl.rs

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