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