http_type/request/
impl.rs

1use crate::*;
2
3/// Provides a default value for `Request`.
4///
5/// Returns a new `Request` instance with all fields initialized to their default values.
6impl Default for Request {
7    #[inline(always)]
8    fn default() -> Self {
9        Self {
10            method: Method::default(),
11            host: String::new(),
12            version: HttpVersion::default(),
13            path: String::new(),
14            querys: hash_map_xx_hash3_64(),
15            headers: hash_map_xx_hash3_64(),
16            body: Vec::new(),
17        }
18    }
19}
20
21impl Request {
22    /// Creates a new instance of `Request`.
23    ///
24    /// # Returns
25    ///
26    /// - `Request` - A new request instance with default values.
27    #[inline(always)]
28    pub fn new() -> Self {
29        Self::default()
30    }
31
32    /// Parses an HTTP request from a buffered TCP stream reader.
33    ///
34    /// Reads request line, headers and body from the stream and constructs a Request object.
35    ///
36    /// # Arguments
37    ///
38    /// - `&mut BufReader<&mut TcpStream>` - The buffered TCP stream reader.
39    /// - `usize` - The buffer size for reading.
40    ///
41    /// # Returns
42    ///
43    /// - `Result<Request, RequestError>` - The parsed request or an error.
44    pub async fn http_from_reader(
45        reader: &mut BufReader<&mut TcpStream>,
46        buffer: usize,
47    ) -> RequestReaderHandleResult {
48        let mut request_line: String = String::with_capacity(buffer.min(DEFAULT_BUFFER_SIZE));
49        let _ = AsyncBufReadExt::read_line(reader, &mut request_line).await;
50        let parts: Vec<&str> = request_line.split_whitespace().collect();
51        let parts_len: usize = parts.len();
52        if parts_len < 3 {
53            return Err(RequestError::InvalidHttpRequestPartsLength(parts_len));
54        }
55        let method: RequestMethod = parts[0]
56            .parse::<RequestMethod>()
57            .unwrap_or(Method::UNKNOWN(parts[0].to_string()));
58        let full_path: RequestPath = parts[1].to_string();
59        let version: RequestVersion = parts[2]
60            .parse::<RequestVersion>()
61            .unwrap_or(RequestVersion::Unknown(parts[2].to_string()));
62        let hash_index: OptionUsize = full_path.find(HASH);
63        let query_index: OptionUsize = full_path.find(QUERY);
64        let query_string: String = query_index.map_or_else(String::new, |i| {
65            let temp: &str = &full_path[i + 1..];
66            if hash_index.is_none() || hash_index.unwrap() <= i {
67                return temp.to_owned();
68            }
69            temp.split(HASH).next().unwrap_or_default().to_owned()
70        });
71        let querys: RequestQuerys = Self::parse_querys(&query_string);
72        let path: RequestPath = if let Some(i) = query_index.or(hash_index) {
73            full_path[..i].to_owned()
74        } else {
75            full_path.to_owned()
76        };
77        let mut headers: RequestHeaders = hash_map_xx_hash3_64();
78        let mut host: RequestHost = String::new();
79        let mut content_length: usize = 0;
80        loop {
81            let mut header_line: String = String::with_capacity(buffer.min(DEFAULT_BUFFER_SIZE));
82            let _ = AsyncBufReadExt::read_line(reader, &mut header_line).await;
83            let header_line: &str = header_line.trim();
84            if header_line.is_empty() {
85                break;
86            }
87            if let Some((key_part, value_part)) = header_line.split_once(COLON) {
88                let key: String = key_part.trim().to_ascii_lowercase();
89                if key.is_empty() {
90                    continue;
91                }
92                let value: String = value_part.trim().to_string();
93                if key == HOST {
94                    host = value.clone();
95                } else if key == CONTENT_LENGTH {
96                    content_length = value.parse().unwrap_or(0);
97                }
98                headers.entry(key).or_default().push_back(value);
99            }
100        }
101        let mut body: RequestBody = vec![0; content_length];
102        if content_length > 0 {
103            let _ = AsyncReadExt::read_exact(reader, &mut body).await;
104        }
105        Ok(Request {
106            method,
107            host,
108            version,
109            path,
110            querys,
111            headers,
112            body,
113        })
114    }
115
116    /// Parses an HTTP request from a TCP stream.
117    ///
118    /// Wraps the stream in a buffered reader and delegates to `http_from_reader`.
119    ///
120    /// # Arguments
121    ///
122    /// - `&ArcRwLock<TcpStream>` - The TCP stream to read from.
123    /// - `usize` - The buffer size for reading.
124    ///
125    /// # Returns
126    ///
127    /// - `Result<Request, RequestError>` - The parsed request or an error.
128    pub async fn http_from_stream(
129        stream: &ArcRwLockStream,
130        buffer: usize,
131    ) -> RequestReaderHandleResult {
132        let mut buf_stream: RwLockWriteGuard<'_, TcpStream> = stream.write().await;
133        let mut reader: BufReader<&mut TcpStream> = BufReader::new(&mut buf_stream);
134        Self::http_from_reader(&mut reader, buffer).await
135    }
136
137    /// Parses a WebSocket request from a TCP stream.
138    ///
139    /// Wraps the stream in a buffered reader and delegates to `ws_from_reader`.
140    ///
141    /// # Arguments
142    ///
143    /// - `&ArcRwLock<TcpStream>` - The TCP stream to read from.
144    /// - `usize` - The buffer size for reading.
145    /// - `&mut Request` - The request template to populate.
146    ///
147    /// # Returns
148    ///
149    /// - `Result<Request, RequestError>` - The parsed WebSocket request or an error.
150    pub async fn ws_from_stream(
151        stream: &ArcRwLockStream,
152        buffer: usize,
153        request: &mut Self,
154    ) -> RequestReaderHandleResult {
155        let mut buf_stream: RwLockWriteGuard<'_, TcpStream> = stream.write().await;
156        let mut reader: BufReader<&mut TcpStream> = BufReader::new(&mut buf_stream);
157        Self::ws_from_reader(&mut reader, buffer, request).await
158    }
159
160    /// Parses a WebSocket request from a buffered TCP stream.
161    ///
162    /// Handles WebSocket frames including text, binary, ping, pong and close frames.
163    /// Assembles the request body from frame payload data.
164    ///
165    /// # Arguments
166    ///
167    /// - `&mut BufReader<&mut TcpStream>` - The buffered TCP stream reader.
168    /// - `usize` - The buffer size for reading frames.
169    /// - `&mut Request` - The request template to populate.
170    ///
171    /// # Returns
172    ///
173    /// - `Result<Request, RequestError>` - The parsed WebSocket request or an error.
174    pub async fn ws_from_reader(
175        reader: &mut BufReader<&mut TcpStream>,
176        buffer: usize,
177        request: &mut Self,
178    ) -> RequestReaderHandleResult {
179        let mut dynamic_buffer: Vec<u8> = Vec::with_capacity(buffer.min(DEFAULT_BUFFER_SIZE));
180        let temp_buffer_size: usize = buffer.min(DEFAULT_BUFFER_SIZE);
181        let mut temp_buffer: Vec<u8> = vec![0; temp_buffer_size];
182        let mut full_frame: Vec<u8> = Vec::with_capacity(buffer.min(MAX_FRAME_SIZE));
183        let mut error_handle = || {
184            request.body.clear();
185        };
186        loop {
187            let len: usize = match reader.read(&mut temp_buffer).await {
188                Ok(len) => len,
189                Err(err) => {
190                    error_handle();
191                    if err.kind() == ErrorKind::ConnectionReset
192                        || err.kind() == ErrorKind::ConnectionAborted
193                    {
194                        return Err(RequestError::ClientDisconnected);
195                    }
196                    return Err(RequestError::InvalidWebSocketRequest(err.to_string()));
197                }
198            };
199            if len == 0 {
200                error_handle();
201                return Err(RequestError::IncompleteWebSocketFrame);
202            }
203            dynamic_buffer.extend_from_slice(&temp_buffer[..len]);
204            while let Some((frame, consumed)) = WebSocketFrame::decode_ws_frame(&dynamic_buffer) {
205                dynamic_buffer.drain(0..consumed);
206                match frame.get_opcode() {
207                    WebSocketOpcode::Close => {
208                        error_handle();
209                        return Err(RequestError::ClientClosedConnection);
210                    }
211                    WebSocketOpcode::Ping | WebSocketOpcode::Pong => {
212                        continue;
213                    }
214                    WebSocketOpcode::Text | WebSocketOpcode::Binary => {
215                        full_frame.extend_from_slice(frame.get_payload_data());
216                        if *frame.get_fin() {
217                            let mut request: Request = request.clone();
218                            request.body = full_frame;
219                            return Ok(request);
220                        }
221                    }
222                    _ => {
223                        error_handle();
224                        return Err(RequestError::InvalidWebSocketFrame(
225                            "Unsupported opcode".to_owned(),
226                        ));
227                    }
228                }
229            }
230        }
231    }
232
233    /// Parses a query string as_ref key-value pairs.
234    ///
235    /// Expects format "key1=value1&key2=value2". Empty values are allowed.
236    ///
237    /// # Arguments
238    ///
239    /// - `&str` - The query string to parse.
240    ///
241    /// # Returns
242    ///
243    /// - `HashMap<String, String>` - The parsed query parameters.
244    fn parse_querys<Q>(query: Q) -> RequestQuerys
245    where
246        Q: AsRef<str>,
247    {
248        let mut query_map: RequestQuerys = hash_map_xx_hash3_64();
249        for pair in query.as_ref().split(AND) {
250            if let Some((key, value)) = pair.split_once(EQUAL) {
251                if !key.is_empty() {
252                    query_map.insert(key.to_string(), value.to_string());
253                }
254            } else if !pair.is_empty() {
255                query_map.insert(pair.to_string(), String::new());
256            }
257        }
258        query_map
259    }
260
261    /// Tries to get a query parameter value by key.
262    ///
263    /// The key type must implement AsRef<str> conversion.
264    ///
265    /// # Arguments
266    ///
267    /// - `AsRef<str>` - The query parameter key (implements AsRef<str>).
268    ///
269    /// # Returns
270    ///
271    /// - `OptionRequestQuerysValue` - The parameter value if exists.
272    #[inline(always)]
273    pub fn try_get_query<K>(&self, key: K) -> OptionRequestQuerysValue
274    where
275        K: AsRef<str>,
276    {
277        self.querys.get(key.as_ref()).cloned()
278    }
279
280    /// Gets a query parameter value by key.
281    ///
282    /// The key type must implement AsRef<str> conversion.
283    ///
284    /// # Arguments
285    ///
286    /// - `AsRef<str>` - The query parameter key (implements AsRef<str>).
287    ///
288    /// # Returns
289    ///
290    /// - `RequestQuerysValue` - The parameter value if exists.
291    ///
292    /// # Panics
293    ///
294    /// This function will panic if the query parameter key is not found.
295    #[inline(always)]
296    pub fn get_query<K>(&self, key: K) -> RequestQuerysValue
297    where
298        K: AsRef<str>,
299    {
300        self.try_get_query(key).unwrap()
301    }
302
303    /// Tries to retrieve the value of a request header by its key.
304    ///
305    /// # Arguments
306    ///
307    /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
308    ///
309    /// # Returns
310    ///
311    /// - `OptionRequestHeadersValue` - The optional header values.
312    #[inline(always)]
313    pub fn try_get_header<K>(&self, key: K) -> OptionRequestHeadersValue
314    where
315        K: AsRef<str>,
316    {
317        self.headers.get(key.as_ref()).cloned()
318    }
319
320    /// Retrieves the value of a request header by its key.
321    ///
322    /// # Arguments
323    ///
324    /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
325    ///
326    /// # Returns
327    ///
328    /// - `RequestHeadersValue` - The optional header values.
329    ///
330    /// # Panics
331    ///
332    /// This function will panic if the header key is not found.
333    #[inline(always)]
334    pub fn get_header<K>(&self, key: K) -> RequestHeadersValue
335    where
336        K: AsRef<str>,
337    {
338        self.try_get_header(key).unwrap()
339    }
340
341    /// Tries to retrieve the first value of a request header by its key.
342    ///
343    /// # Arguments
344    ///
345    /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
346    ///
347    /// # Returns
348    ///
349    /// - `OptionRequestHeadersValueItem` - The first header value if exists.
350    #[inline(always)]
351    pub fn try_get_header_front<K>(&self, key: K) -> OptionRequestHeadersValueItem
352    where
353        K: AsRef<str>,
354    {
355        self.headers
356            .get(key.as_ref())
357            .and_then(|values| values.front().cloned())
358    }
359
360    /// Retrieves the first value of a request header by its key.
361    ///
362    /// # Arguments
363    ///
364    /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
365    ///
366    /// # Returns
367    ///
368    /// - `RequestHeadersValueItem` - The first header value if exists.
369    ///
370    /// # Panics
371    ///
372    /// This function will panic if the header key is not found.
373    #[inline(always)]
374    pub fn get_header_front<K>(&self, key: K) -> RequestHeadersValueItem
375    where
376        K: AsRef<str>,
377    {
378        self.try_get_header_front(key).unwrap()
379    }
380
381    /// Tries to retrieve the last value of a request header by its key.
382    ///
383    /// # Arguments
384    ///
385    /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
386    ///
387    /// # Returns
388    ///
389    /// - `OptionRequestHeadersValueItem` - The last header value if exists.
390    #[inline(always)]
391    pub fn try_get_header_back<K>(&self, key: K) -> OptionRequestHeadersValueItem
392    where
393        K: AsRef<str>,
394    {
395        self.headers
396            .get(key.as_ref())
397            .and_then(|values| values.back().cloned())
398    }
399
400    /// Retrieves the last value of a request header by its key.
401    ///
402    /// # Arguments
403    ///
404    /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
405    ///
406    /// # Returns
407    ///
408    /// - `RequestHeadersValueItem` - The last header value if exists.
409    ///
410    /// # Panics
411    ///
412    /// This function will panic if the header key is not found.
413    #[inline(always)]
414    pub fn get_header_back<K>(&self, key: K) -> RequestHeadersValueItem
415    where
416        K: AsRef<str>,
417    {
418        self.try_get_header_back(key).unwrap()
419    }
420
421    /// Tries to retrieve the number of values for a specific header.
422    ///
423    /// # Arguments
424    ///
425    /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
426    ///
427    /// # Returns
428    ///
429    /// - `OptionUsize` - The count of values for the header if exists.
430    #[inline(always)]
431    pub fn try_get_header_length<K>(&self, key: K) -> OptionUsize
432    where
433        K: AsRef<str>,
434    {
435        self.headers.get(key.as_ref()).map(|values| values.len())
436    }
437
438    /// Retrieves the number of values for a specific header.
439    ///
440    /// # Arguments
441    ///
442    /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
443    ///
444    /// # Returns
445    ///
446    /// - `usize` - The count of values for the header.
447    ///
448    /// # Panics
449    ///
450    /// This function will panic if the header key is not found.
451    #[inline(always)]
452    pub fn get_header_length<K>(&self, key: K) -> usize
453    where
454        K: AsRef<str>,
455    {
456        self.try_get_header_length(key).unwrap()
457    }
458
459    /// Retrieves the total number of header values across all headers.
460    ///
461    /// # Returns
462    ///
463    /// - `usize` - The total count of all header values.
464    #[inline(always)]
465    pub fn get_headers_values_length(&self) -> usize {
466        self.headers.values().map(|values| values.len()).sum()
467    }
468
469    /// Retrieves the number of unique headers.
470    ///
471    /// # Returns
472    ///
473    /// - `usize` - The count of unique header keys.
474    #[inline(always)]
475    pub fn get_headers_length(&self) -> usize {
476        self.headers.len()
477    }
478
479    /// Checks if a specific header exists.
480    ///
481    /// # Arguments
482    ///
483    /// - `AsRef<str>` - The header key to check (must implement AsRef<str>).
484    ///
485    /// # Returns
486    ///
487    /// - `bool` - Whether the header exists.
488    #[inline(always)]
489    pub fn has_header<K>(&self, key: K) -> bool
490    where
491        K: AsRef<str>,
492    {
493        self.headers.contains_key(key.as_ref())
494    }
495
496    /// Checks if a header contains a specific value.
497    ///
498    /// # Arguments
499    ///
500    /// - `AsRef<str>` - The header key to check (must implement AsRef<str>).
501    /// - `AsRef<str>` - The value to search for (must implement AsRef<str>).
502    ///
503    /// # Returns
504    ///
505    /// - `bool` - Whether the header contains the value.
506    #[inline(always)]
507    pub fn has_header_value<K, V>(&self, key: K, value: V) -> bool
508    where
509        K: AsRef<str>,
510        V: AsRef<str>,
511    {
512        if let Some(values) = self.headers.get(key.as_ref()) {
513            values.contains(&value.as_ref().to_owned())
514        } else {
515            false
516        }
517    }
518
519    /// Retrieves the body content of the request as a UTF-8 encoded string.
520    ///
521    /// This method uses `String::from_utf8_lossy` to convert the byte slice returned by `self.get_body()` as_ref a string.
522    /// If the byte slice contains invalid UTF-8 sequences, they will be replaced with the Unicode replacement character ().
523    ///
524    /// # Returns
525    ///
526    /// - `String` - The body content as a string.
527    #[inline(always)]
528    pub fn get_body_string(&self) -> String {
529        String::from_utf8_lossy(self.get_body()).into_owned()
530    }
531
532    /// Deserializes the body content of the request as_ref a specified type `T`.
533    ///
534    /// This method first retrieves the body content as a byte slice using `self.get_body()`.
535    /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
536    ///
537    /// # Arguments
538    ///
539    /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
540    ///
541    /// # Returns
542    ///
543    /// - `ResultJsonError<T>` - The deserialization result.
544    pub fn try_get_body_json<T>(&self) -> ResultJsonError<T>
545    where
546        T: DeserializeOwned,
547    {
548        json_from_slice(self.get_body())
549    }
550
551    /// Deserializes the body content of the request as_ref a specified type `T`.
552    ///
553    /// This method first retrieves the body content as a byte slice using `self.get_body()`.
554    /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
555    ///
556    /// # Arguments
557    ///
558    /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
559    ///
560    /// # Returns
561    ///
562    /// - `T` - The deserialized body content.
563    ///
564    /// # Panics
565    ///
566    /// This function will panic if the deserialization fails.
567    pub fn get_body_json<T>(&self) -> T
568    where
569        T: DeserializeOwned,
570    {
571        self.try_get_body_json().unwrap()
572    }
573
574    /// Converts the request to a formatted string representation.
575    ///
576    /// This method provides a human-readable summary of the request, including its method,
577    /// host, version, path, query parameters, headers, and body information.
578    ///
579    /// # Returns
580    ///
581    /// - `String` - The formatted request details.
582    #[inline(always)]
583    pub fn get_string(&self) -> String {
584        let body: &Vec<u8> = self.get_body();
585        let body_type: &'static str = if std::str::from_utf8(body).is_ok() {
586            PLAIN
587        } else {
588            BINARY
589        };
590        format!(
591            "[Request] => [method]: {}; [host]: {}; [version]: {}; [path]: {}; [querys]: {:?}; [headers]: {:?}; [body]: {} bytes {};",
592            self.get_method(),
593            self.get_host(),
594            self.get_version(),
595            self.get_path(),
596            self.get_querys(),
597            self.get_headers(),
598            body.len(),
599            body_type
600        )
601    }
602
603    /// Retrieves the upgrade type from the request headers.
604    ///
605    /// This method looks for the `UPGRADE` header and attempts to parse its value
606    /// as_ref an `UpgradeType`. If the header is missing or the value is invalid,
607    /// it returns the default `UpgradeType`.
608    ///
609    /// # Returns
610    ///
611    /// - `UpgradeType` - The parsed upgrade type.
612    #[inline(always)]
613    pub fn get_upgrade_type(&self) -> UpgradeType {
614        let upgrade_type: UpgradeType = self
615            .try_get_header_back(UPGRADE)
616            .and_then(|data| data.parse::<UpgradeType>().ok())
617            .unwrap_or_default();
618        upgrade_type
619    }
620
621    /// Checks whether the WebSocket upgrade is enabled for this request.
622    ///
623    /// This method determines if the `UPGRADE` header indicates a WebSocket connection.
624    ///
625    /// # Returns
626    ///
627    /// - `bool` - Whether WebSocket upgrade is enabled.
628    #[inline(always)]
629    pub fn is_ws(&self) -> bool {
630        self.get_upgrade_type().is_ws()
631    }
632
633    /// Checks if the current upgrade type is HTTP/2 cleartext (h2c).
634    ///
635    /// # Returns
636    ///
637    /// - `bool` - Whether the upgrade type is h2c.
638    #[inline(always)]
639    pub fn is_h2c(&self) -> bool {
640        self.get_upgrade_type().is_h2c()
641    }
642
643    /// Checks if the current upgrade type is TLS (any version).
644    ///
645    /// # Returns
646    ///
647    /// - `bool` - Whether the upgrade type is TLS.
648    #[inline(always)]
649    pub fn is_tls(&self) -> bool {
650        self.get_upgrade_type().is_tls()
651    }
652
653    /// Checks whether the upgrade type is unknown.
654    ///
655    /// # Returns
656    ///
657    /// - `bool` - Whether the upgrade type is unknown.
658    #[inline(always)]
659    pub fn is_unknown_upgrade(&self) -> bool {
660        self.get_upgrade_type().is_unknown()
661    }
662
663    /// Checks if the HTTP version is HTTP/1.1 or higher.
664    ///
665    /// # Returns
666    ///
667    /// - `bool` - Whether the version is HTTP/1.1 or higher.
668    #[inline(always)]
669    pub fn is_http1_1_or_higher(&self) -> bool {
670        self.get_version().is_http1_1_or_higher()
671    }
672
673    /// Checks whether the HTTP version is HTTP/0.9.
674    ///
675    /// # Returns
676    ///
677    /// - `bool` - Whether the version is HTTP/0.9.
678    #[inline(always)]
679    pub fn is_http0_9(&self) -> bool {
680        self.get_version().is_http0_9()
681    }
682
683    /// Checks whether the HTTP version is HTTP/1.0.
684    ///
685    /// # Returns
686    ///
687    /// - `bool` - Whether the version is HTTP/1.0.
688    #[inline(always)]
689    pub fn is_http1_0(&self) -> bool {
690        self.get_version().is_http1_0()
691    }
692
693    /// Checks whether the HTTP version is HTTP/1.1.
694    ///
695    /// # Returns
696    ///
697    /// - `bool` - Whether the version is HTTP/1.1.
698    #[inline(always)]
699    pub fn is_http1_1(&self) -> bool {
700        self.get_version().is_http1_1()
701    }
702
703    /// Checks whether the HTTP version is HTTP/2.
704    ///
705    /// # Returns
706    ///
707    /// - `bool` - Whether the version is HTTP/2.
708    #[inline(always)]
709    pub fn is_http2(&self) -> bool {
710        self.get_version().is_http2()
711    }
712
713    /// Checks whether the HTTP version is HTTP/3.
714    ///
715    /// # Returns
716    ///
717    /// - `bool` - Whether the version is HTTP/3.
718    #[inline(always)]
719    pub fn is_http3(&self) -> bool {
720        self.get_version().is_http3()
721    }
722
723    /// Checks whether the HTTP version is unknown.
724    ///
725    /// # Returns
726    ///
727    /// - `bool` - Whether the version is unknown.
728    #[inline(always)]
729    pub fn is_unknown_version(&self) -> bool {
730        self.get_version().is_unknown()
731    }
732
733    /// Checks whether the version belongs to the HTTP family.
734    ///
735    /// # Returns
736    ///
737    /// - `bool` - Whether the version is HTTP.
738    #[inline(always)]
739    pub fn is_http(&self) -> bool {
740        self.get_version().is_http()
741    }
742
743    /// Checks whether the request method is GET.
744    ///
745    /// # Returns
746    ///
747    /// - `bool` - Whether the method is GET.
748    #[inline(always)]
749    pub fn is_get(&self) -> bool {
750        self.get_method().is_get()
751    }
752
753    /// Checks whether the request method is POST.
754    ///
755    /// # Returns
756    ///
757    /// - `bool` - Whether the method is POST.
758    #[inline(always)]
759    pub fn is_post(&self) -> bool {
760        self.get_method().is_post()
761    }
762
763    /// Checks whether the request method is PUT.
764    ///
765    /// # Returns
766    ///
767    /// - `bool` - Whether the method is PUT.
768    #[inline(always)]
769    pub fn is_put(&self) -> bool {
770        self.get_method().is_put()
771    }
772
773    /// Checks whether the request method is DELETE.
774    ///
775    /// # Returns
776    ///
777    /// - `bool` - Whether the method is DELETE.
778    #[inline(always)]
779    pub fn is_delete(&self) -> bool {
780        self.get_method().is_delete()
781    }
782
783    /// Checks whether the request method is PATCH.
784    ///
785    /// # Returns
786    ///
787    /// - `bool` - Whether the method is PATCH.
788    #[inline(always)]
789    pub fn is_patch(&self) -> bool {
790        self.get_method().is_patch()
791    }
792
793    /// Checks whether the request method is HEAD.
794    ///
795    /// # Returns
796    ///
797    /// - `bool` - Whether the method is HEAD.
798    #[inline(always)]
799    pub fn is_head(&self) -> bool {
800        self.get_method().is_head()
801    }
802
803    /// Checks whether the request method is OPTIONS.
804    ///
805    /// # Returns
806    ///
807    /// - `bool` - Whether the method is OPTIONS.
808    #[inline(always)]
809    pub fn is_options(&self) -> bool {
810        self.get_method().is_options()
811    }
812
813    /// Checks whether the request method is CONNECT.
814    ///
815    /// # Returns
816    ///
817    /// - `bool` - Whether the method is CONNECT.
818    #[inline(always)]
819    pub fn is_connect(&self) -> bool {
820        self.get_method().is_connect()
821    }
822
823    /// Checks whether the request method is TRACE.
824    ///
825    /// # Returns
826    ///
827    /// - `bool` - Whether the method is TRACE.
828    #[inline(always)]
829    pub fn is_trace(&self) -> bool {
830        self.get_method().is_trace()
831    }
832
833    /// Checks whether the request method is UNKNOWN.
834    ///
835    /// # Returns
836    ///
837    /// - `bool` - Whether the method is UNKNOWN.
838    #[inline(always)]
839    pub fn is_unknown_method(&self) -> bool {
840        self.get_method().is_unknown()
841    }
842
843    /// Determines if a keep-alive connection should be enabled for this request.
844    ///
845    /// This function checks the `Connection` header and the HTTP version to determine
846    /// if keep-alive should be enabled. The logic is as follows:
847    ///
848    /// 1. If the `Connection` header exists:
849    ///    - Returns `true` if the header value is "keep-alive" (case-insensitive).
850    ///    - Returns `false` if the header value is "close" (case-insensitive).
851    /// 2. If no `Connection` header is present:
852    ///    - Returns `true` if the HTTP version is 1.1 or higher.
853    ///    - Returns `false` otherwise.
854    ///
855    /// # Returns
856    ///
857    /// - `bool` - Whether keep-alive should be enabled.
858    #[inline(always)]
859    pub fn is_enable_keep_alive(&self) -> bool {
860        if let Some(connection_value) = self.try_get_header_back(CONNECTION) {
861            if connection_value.eq_ignore_ascii_case(KEEP_ALIVE) {
862                return true;
863            } else if connection_value.eq_ignore_ascii_case(CLOSE) {
864                return self.is_ws();
865            }
866        }
867        self.is_http1_1_or_higher() || self.is_ws()
868    }
869
870    /// Determines if keep-alive should be disabled for this request.
871    ///
872    /// # Returns
873    ///
874    /// - `bool` - Whether keep-alive should be disabled.
875    #[inline(always)]
876    pub fn is_disable_keep_alive(&self) -> bool {
877        !self.is_enable_keep_alive()
878    }
879}