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