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
17/// Converts an I/O error to a `RequestError`.
18///
19/// Maps connection reset and aborted errors to `ClientDisconnected`,
20/// all other I/O errors are mapped to `ReadConnection`.
21impl From<std::io::Error> for RequestError {
22 /// Converts an I/O error to a `RequestError`.
23 ///
24 /// # Arguments
25 ///
26 /// - `std::io::Error`: The I/O error to convert.
27 ///
28 /// # Returns
29 ///
30 /// - `RequestError`: The corresponding request error.
31 #[inline(always)]
32 fn from(error: std::io::Error) -> Self {
33 let kind: ErrorKind = error.kind();
34 if kind == ErrorKind::ConnectionReset || kind == ErrorKind::ConnectionAborted {
35 return RequestError::ClientDisconnected(HttpStatus::BadRequest);
36 }
37 RequestError::ReadConnection(HttpStatus::BadRequest)
38 }
39}
40
41/// Converts a timeout elapsed error to a `RequestError`.
42///
43/// Maps timeout errors to `ReadTimeout` with `HttpStatus::RequestTimeout`.
44impl From<Elapsed> for RequestError {
45 /// Converts a timeout elapsed error to a `RequestError`.
46 ///
47 /// # Arguments
48 ///
49 /// - `Elapsed`: The elapsed error to convert.
50 ///
51 /// # Returns
52 ///
53 /// - `RequestError`: The corresponding request error as `ReadTimeout`.
54 #[inline(always)]
55 fn from(_: Elapsed) -> Self {
56 RequestError::ReadTimeout(HttpStatus::RequestTimeout)
57 }
58}
59
60/// Converts a parse int error to a `RequestError`.
61///
62/// Maps parse int errors to `InvalidContentLength` with `HttpStatus::BadRequest`.
63impl From<ParseIntError> for RequestError {
64 /// Converts a parse int error to a `RequestError`.
65 ///
66 /// # Arguments
67 ///
68 /// - `ParseIntError`: The parse error to convert.
69 ///
70 /// # Returns
71 ///
72 /// - `RequestError`: The corresponding request error as `InvalidContentLength`.
73 #[inline(always)]
74 fn from(_: ParseIntError) -> Self {
75 RequestError::InvalidContentLength(HttpStatus::BadRequest)
76 }
77}
78
79/// Converts a response error to a `RequestError`.
80///
81/// Maps response errors to `WriteTimeout` with `HttpStatus::InternalServerError`.
82impl From<ResponseError> for RequestError {
83 /// Converts a response error to a `RequestError`.
84 ///
85 /// # Arguments
86 ///
87 /// - `ResponseError`: The response error to convert.
88 ///
89 /// # Returns
90 ///
91 /// - `RequestError`: The corresponding request error as `WriteTimeout`.
92 #[inline(always)]
93 fn from(_: ResponseError) -> Self {
94 RequestError::WriteTimeout(HttpStatus::InternalServerError)
95 }
96}
97
98impl RequestError {
99 /// Gets the HTTP status associated with this error.
100 ///
101 /// Returns the HttpStatus enum variant that corresponds to this error.
102 ///
103 /// # Returns
104 ///
105 /// - `HttpStatus` - The HTTP status associated with this error.
106 pub fn get_http_status(&self) -> HttpStatus {
107 match self {
108 Self::HttpRead(status) => *status,
109 Self::GetTcpStream(status) => *status,
110 Self::GetTlsStream(status) => *status,
111 Self::ReadConnection(status) => *status,
112 Self::RequestAborted(status) => *status,
113 Self::TlsStreamConnect(status) => *status,
114 Self::NeedOpenRedirect(status) => *status,
115 Self::MaxRedirectTimes(status) => *status,
116 Self::MethodsNotSupport(status) => *status,
117 Self::RedirectInvalidUrl(status) => *status,
118 Self::ClientDisconnected(status) => *status,
119 Self::RedirectUrlDeadLoop(status) => *status,
120 Self::ClientClosedConnection(status) => *status,
121 Self::IncompleteWebSocketFrame(status) => *status,
122 Self::RequestTooLong(status) => *status,
123 Self::PathTooLong(status) => *status,
124 Self::QueryTooLong(status) => *status,
125 Self::HeaderLineTooLong(status) => *status,
126 Self::TooManyHeaders(status) => *status,
127 Self::HeaderKeyTooLong(status) => *status,
128 Self::HeaderValueTooLong(status) => *status,
129 Self::ContentLengthTooLarge(status) => *status,
130 Self::InvalidContentLength(status) => *status,
131 Self::InvalidUrlScheme(status) => *status,
132 Self::InvalidUrlHost(status) => *status,
133 Self::InvalidUrlPort(status) => *status,
134 Self::InvalidUrlPath(status) => *status,
135 Self::InvalidUrlQuery(status) => *status,
136 Self::InvalidUrlFragment(status) => *status,
137 Self::ReadTimeout(status) => *status,
138 Self::WriteTimeout(status) => *status,
139 Self::TcpConnectionFailed(status) => *status,
140 Self::TlsHandshakeFailed(status) => *status,
141 Self::TlsCertificateInvalid(status) => *status,
142 Self::WebSocketFrameTooLarge(status) => *status,
143 Self::WebSocketOpcodeUnsupported(status) => *status,
144 Self::WebSocketMaskMissing(status) => *status,
145 Self::WebSocketPayloadCorrupted(status) => *status,
146 Self::WebSocketInvalidUtf8(status) => *status,
147 Self::WebSocketInvalidCloseCode(status) => *status,
148 Self::WebSocketInvalidExtension(status) => *status,
149 Self::HttpRequestPartsInsufficient(status) => *status,
150 Self::TcpStreamConnect(status) => *status,
151 Self::TlsConnectorBuild(status) => *status,
152 Self::InvalidUrl(status) => *status,
153 Self::ConfigReadError(status) => *status,
154 Self::TcpStreamConnectString(status) => *status,
155 Self::TlsConnectorBuildString(status) => *status,
156 Self::Request(_) => HttpStatus::BadRequest,
157 Self::Unknown(status) => *status,
158 }
159 }
160
161 /// Gets the numeric HTTP status code associated with this error.
162 ///
163 /// Returns the numeric status code (e.g., 400, 404, 500) that corresponds to this error.
164 ///
165 /// # Returns
166 ///
167 /// - `ResponseStatusCode` - The numeric HTTP status code.
168 pub fn get_http_status_code(&self) -> ResponseStatusCode {
169 self.get_http_status().code()
170 }
171}
172
173impl Default for RequestConfigData {
174 /// Creates a `RequestConfig` with secure default values.
175 ///
176 /// # Returns
177 ///
178 /// - `RequestConfigData ` - A new config instance with secure defaults.
179 #[inline(always)]
180 fn default() -> Self {
181 Self {
182 buffer_size: DEFAULT_BUFFER_SIZE,
183 max_request_line_size: DEFAULT_MAX_REQUEST_LINE_SIZE,
184 max_path_size: DEFAULT_MAX_PATH_SIZE,
185 max_query_size: DEFAULT_MAX_QUERY_SIZE,
186 max_header_line_size: DEFAULT_MAX_HEADER_LINE_SIZE,
187 max_header_count: DEFAULT_MAX_HEADER_COUNT,
188 max_header_key_size: DEFAULT_MAX_HEADER_KEY_SIZE,
189 max_header_value_size: DEFAULT_MAX_HEADER_VALUE_SIZE,
190 max_body_size: DEFAULT_MAX_BODY_SIZE,
191 max_ws_frame_size: DEFAULT_MAX_WS_FRAME_SIZE,
192 max_ws_frames_count: DEFAULT_MAX_WS_FRAMES_COUNT,
193 http_read_timeout_ms: DEFAULT_HTTP_READ_TIMEOUT_MS,
194 ws_read_timeout_ms: DEFAULT_WS_READ_TIMEOUT_MS,
195 }
196 }
197}
198
199impl RequestConfigData {
200 /// Creates a config optimized for low-security environments.
201 ///
202 /// This configuration uses less restrictive limits to provide
203 /// basic protection against common attacks.
204 ///
205 /// # Returns
206 ///
207 /// - `RequestConfigData ` - A new config with low-security settings.
208 #[inline(always)]
209 pub(super) fn low_security() -> Self {
210 Self {
211 buffer_size: DEFAULT_LOW_SECURITY_BUFFER_SIZE,
212 max_request_line_size: DEFAULT_LOW_SECURITY_MAX_REQUEST_LINE_SIZE,
213 max_path_size: DEFAULT_LOW_SECURITY_MAX_PATH_SIZE,
214 max_query_size: DEFAULT_LOW_SECURITY_MAX_QUERY_SIZE,
215 max_header_line_size: DEFAULT_LOW_SECURITY_MAX_HEADER_LINE_SIZE,
216 max_header_count: DEFAULT_LOW_SECURITY_MAX_HEADER_COUNT,
217 max_header_key_size: DEFAULT_LOW_SECURITY_MAX_HEADER_KEY_SIZE,
218 max_header_value_size: DEFAULT_LOW_SECURITY_MAX_HEADER_VALUE_SIZE,
219 max_body_size: DEFAULT_LOW_SECURITY_MAX_BODY_SIZE,
220 max_ws_frame_size: DEFAULT_LOW_SECURITY_MAX_WS_FRAME_SIZE,
221 max_ws_frames_count: DEFAULT_LOW_SECURITY_MAX_WS_FRAMES_COUNT,
222 http_read_timeout_ms: DEFAULT_LOW_SECURITY_HTTP_READ_TIMEOUT_MS,
223 ws_read_timeout_ms: DEFAULT_LOW_SECURITY_WS_READ_TIMEOUT_MS,
224 }
225 }
226
227 /// Creates a config optimized for high-security environments.
228 ///
229 /// This configuration uses more restrictive limits to provide
230 /// maximum protection against various attacks.
231 ///
232 /// # Returns
233 ///
234 /// - `RequestConfigData ` - A new config with high-security settings.
235 #[inline(always)]
236 pub(super) fn high_security() -> Self {
237 Self {
238 buffer_size: DEFAULT_HIGH_SECURITY_BUFFER_SIZE,
239 max_request_line_size: DEFAULT_HIGH_SECURITY_MAX_REQUEST_LINE_SIZE,
240 max_path_size: DEFAULT_HIGH_SECURITY_MAX_PATH_SIZE,
241 max_query_size: DEFAULT_HIGH_SECURITY_MAX_QUERY_SIZE,
242 max_header_line_size: DEFAULT_HIGH_SECURITY_MAX_HEADER_LINE_SIZE,
243 max_header_count: DEFAULT_HIGH_SECURITY_MAX_HEADER_COUNT,
244 max_header_key_size: DEFAULT_HIGH_SECURITY_MAX_HEADER_KEY_SIZE,
245 max_header_value_size: DEFAULT_HIGH_SECURITY_MAX_HEADER_VALUE_SIZE,
246 max_body_size: DEFAULT_HIGH_SECURITY_MAX_BODY_SIZE,
247 max_ws_frame_size: DEFAULT_HIGH_SECURITY_MAX_WS_FRAME_SIZE,
248 max_ws_frames_count: DEFAULT_HIGH_SECURITY_MAX_WS_FRAMES_COUNT,
249 http_read_timeout_ms: DEFAULT_HIGH_SECURITY_HTTP_READ_TIMEOUT_MS,
250 ws_read_timeout_ms: DEFAULT_HIGH_SECURITY_WS_READ_TIMEOUT_MS,
251 }
252 }
253}
254
255/// Implementation of `Default` trait for `RequestConfig`.
256impl Default for RequestConfig {
257 /// Creates a new `RequestConfig` with default secure settings.
258 ///
259 /// This constructor initializes the configuration with standard security limits
260 /// suitable for most HTTP request parsing scenarios.
261 ///
262 /// # Returns
263 ///
264 /// - `Self` - A new `RequestConfig` instance with default settings.
265 #[inline(always)]
266 fn default() -> Self {
267 Self(arc_rwlock(RequestConfigData::default()))
268 }
269}
270
271/// Implementation of `PartialEq` trait for `RequestConfig`.
272impl PartialEq for RequestConfig {
273 /// Compares two `RequestConfig` instances for equality.
274 ///
275 /// # Arguments
276 ///
277 /// - `other` - The second `RequestConfig` instance to compare.
278 ///
279 /// # Returns
280 ///
281 /// - `bool` - `true` if the instances are equal, `false` otherwise.
282 fn eq(&self, other: &Self) -> bool {
283 if Arc::ptr_eq(self.get_0(), other.get_0()) {
284 return true;
285 }
286 if let (Ok(s), Ok(o)) = (self.get_0().try_read(), other.get_0().try_read()) {
287 *s == *o
288 } else {
289 false
290 }
291 }
292}
293
294/// Implementation of `Eq` trait for `RequestConfig`.
295impl Eq for RequestConfig {}
296
297/// Implementation of `From` trait for `RequestConfig`.
298impl From<RequestConfigData> for RequestConfig {
299 /// Converts a `RequestConfigData` into a `RequestConfig`.
300 ///
301 /// # Arguments
302 ///
303 /// - `RequestConfigData` - The wrapped context data.
304 ///
305 /// # Returns
306 ///
307 /// - `RequestConfig` - The newly created context instance.
308 #[inline(always)]
309 fn from(ctx: RequestConfigData) -> Self {
310 Self(arc_rwlock(ctx))
311 }
312}
313
314impl RequestConfig {
315 /// Creates a new `RequestConfig` with default secure settings.
316 ///
317 /// This constructor initializes the configuration with standard security limits
318 /// suitable for most HTTP request parsing scenarios.
319 ///
320 /// # Returns
321 ///
322 /// - `Self` - A new `RequestConfig` instance with default settings.
323 pub async fn new() -> Self {
324 Self(arc_rwlock(RequestConfigData::default()))
325 }
326
327 /// Creates a new `RequestConfig` from a JSON string.
328 ///
329 /// # Arguments
330 ///
331 /// - `AsRef<str>` - The configuration.
332 ///
333 /// # Returns
334 ///
335 /// - `Result<RequestConfig, serde_json::Error>` - The parsed `RequestConfig` or an error.
336 pub fn from_json<C>(json: C) -> Result<RequestConfig, serde_json::Error>
337 where
338 C: AsRef<str>,
339 {
340 serde_json::from_str(json.as_ref()).map(|data: RequestConfigData| Self::from(data))
341 }
342
343 /// Creates a new `RequestConfig` with low-security settings.
344 ///
345 /// This constructor initializes the configuration with less restrictive limits
346 /// to provide maximum protection against various attacks in high-risk environments.
347 ///
348 /// # Returns
349 ///
350 /// - `Self` - A new `RequestConfig` instance with low-security settings.
351 pub async fn low_security() -> Self {
352 Self(arc_rwlock(RequestConfigData::low_security()))
353 }
354
355 /// Creates a new `RequestConfig` with high-security settings.
356 ///
357 /// This constructor initializes the configuration with more restrictive limits
358 /// to provide maximum protection against various attacks in high-risk environments.
359 ///
360 /// # Returns
361 ///
362 /// - `Self` - A new `RequestConfig` instance with high-security settings.
363 pub async fn high_security() -> Self {
364 Self(arc_rwlock(RequestConfigData::high_security()))
365 }
366
367 /// Acquires a read lock on the inner configuration.
368 ///
369 /// This method returns a `RwLockReadGuard` that allows reading the
370 /// `RequestConfigData ` values. Multiple threads can read concurrently.
371 ///
372 /// # Returns
373 ///
374 /// - `RwLockReadGuard<'_, RequestConfigData >` - A read guard providing access to the inner configuration.
375 async fn read(&'_ self) -> RwLockReadGuard<'_, RequestConfigData> {
376 self.get_0().read().await
377 }
378
379 /// Acquires a write lock on the inner configuration.
380 ///
381 /// This method returns a `RwLockWriteGuard` that allows mutating the
382 /// `RequestConfigData ` values. Write access is exclusive.
383 ///
384 /// # Returns
385 ///
386 /// - `RwLockWriteGuard<'_, RequestConfigData >` - A write guard providing exclusive access to the inner configuration.
387 async fn write(&'_ self) -> RwLockWriteGuard<'_, RequestConfigData> {
388 self.get_0().write().await
389 }
390
391 /// Sets the configuration data.
392 ///
393 /// # Arguments
394 ///
395 /// - `RequestConfigData` - The configuration data.
396 ///
397 /// # Returns
398 ///
399 /// - `&Self` - The RequestConfig instance for chaining.
400 pub async fn data(&self, data: RequestConfigData) -> &Self {
401 *self.write().await = data;
402 self
403 }
404
405 /// Gets the configuration data.
406 ///
407 /// # Returns
408 ///
409 /// - `RequestConfigData ` - The inner configuration.
410 pub async fn get_data(&self) -> RequestConfigData {
411 *self.read().await
412 }
413
414 /// Sets the buffer size for reading operations.
415 ///
416 /// # Arguments
417 ///
418 /// - `usize` - The buffer size in bytes.
419 ///
420 /// # Returns
421 ///
422 /// - `&Self` - The RequestConfig instance for chaining.
423 pub async fn buffer_size(&self, buffer_size: usize) -> &Self {
424 self.write().await.set_buffer_size(buffer_size);
425 self
426 }
427
428 /// Sets the maximum length for HTTP request line in bytes.
429 ///
430 /// # Arguments
431 ///
432 /// - `usize` - The maximum request line size.
433 ///
434 /// # Returns
435 ///
436 /// - `&Self` - The RequestConfig instance for chaining.
437 pub async fn max_request_line_size(&self, size: usize) -> &Self {
438 self.write().await.set_max_request_line_size(size);
439 self
440 }
441
442 /// Sets the maximum length for URL path in bytes.
443 ///
444 /// # Arguments
445 ///
446 /// - `usize` - The maximum path length.
447 ///
448 /// # Returns
449 ///
450 /// - `&Self` - The RequestConfig instance for chaining.
451 pub async fn max_path_size(&self, size: usize) -> &Self {
452 self.write().await.set_max_path_size(size);
453 self
454 }
455
456 /// Sets the maximum length for query string in bytes.
457 ///
458 /// # Arguments
459 ///
460 /// - `usize` - The maximum query string length.
461 ///
462 /// # Returns
463 ///
464 /// - `&Self` - The RequestConfig instance for chaining.
465 pub async fn max_query_size(&self, size: usize) -> &Self {
466 self.write().await.set_max_query_size(size);
467 self
468 }
469
470 /// Sets the maximum length for a single header line in bytes.
471 ///
472 /// # Arguments
473 ///
474 /// - `usize` - The maximum header line size.
475 ///
476 /// # Returns
477 ///
478 /// - `&Self` - The RequestConfig instance for chaining.
479 pub async fn max_header_line_size(&self, size: usize) -> &Self {
480 self.write().await.set_max_header_line_size(size);
481 self
482 }
483
484 /// Sets the maximum number of headers allowed in a request.
485 ///
486 /// # Arguments
487 ///
488 /// - `usize` - The maximum header count.
489 ///
490 /// # Returns
491 ///
492 /// - `&Self` - The RequestConfig instance for chaining.
493 pub async fn max_header_count(&self, count: usize) -> &Self {
494 self.write().await.set_max_header_count(count);
495 self
496 }
497
498 /// Sets the maximum length for a header key in bytes.
499 ///
500 /// # Arguments
501 ///
502 /// - `usize` - The maximum header key length.
503 ///
504 /// # Returns
505 ///
506 /// - `&Self` - The RequestConfig instance for chaining.
507 pub async fn max_header_key_size(&self, size: usize) -> &Self {
508 self.write().await.set_max_header_key_size(size);
509 self
510 }
511
512 /// Sets the maximum length for a header value in bytes.
513 ///
514 /// # Arguments
515 ///
516 /// - `usize` - The maximum header value length.
517 ///
518 /// # Returns
519 ///
520 /// - `&Self` - The RequestConfig instance for chaining.
521 pub async fn max_header_value_size(&self, size: usize) -> &Self {
522 self.write().await.set_max_header_value_size(size);
523 self
524 }
525
526 /// Sets the maximum size for request body in bytes.
527 ///
528 /// # Arguments
529 ///
530 /// - `usize` - The maximum body size.
531 ///
532 /// # Returns
533 ///
534 /// - `&Self` - The RequestConfig instance for chaining.
535 pub async fn max_body_size(&self, size: usize) -> &Self {
536 self.write().await.set_max_body_size(size);
537 self
538 }
539
540 /// Sets the maximum size for WebSocket frame in bytes.
541 ///
542 /// # Arguments
543 ///
544 /// - `usize` - The maximum WebSocket frame size.
545 ///
546 /// # Returns
547 ///
548 /// - `&Self` - The RequestConfig instance for chaining.
549 pub async fn max_ws_frame_size(&self, size: usize) -> &Self {
550 self.write().await.set_max_ws_frame_size(size);
551 self
552 }
553
554 /// Sets the maximum number of WebSocket frames to process in a single request.
555 ///
556 /// # Arguments
557 ///
558 /// - `usize` - The maximum WebSocket frames count.
559 ///
560 /// # Returns
561 ///
562 /// - `&Self` - The RequestConfig instance for chaining.
563 pub async fn max_ws_frames_count(&self, size: usize) -> &Self {
564 self.write().await.set_max_ws_frames_count(size);
565 self
566 }
567
568 /// Sets the timeout for reading HTTP request in milliseconds.
569 ///
570 /// # Arguments
571 ///
572 /// - `u64` - The HTTP read timeout in milliseconds.
573 ///
574 /// # Returns
575 ///
576 /// - `&Self` - The RequestConfig instance for chaining.
577 pub async fn http_read_timeout_ms(&self, http_read_timeout_ms: u64) -> &Self {
578 self.write()
579 .await
580 .set_http_read_timeout_ms(http_read_timeout_ms);
581 self
582 }
583
584 /// Sets the timeout for reading WebSocket frames in milliseconds.
585 ///
586 /// # Arguments
587 ///
588 /// - `u64` - The WebSocket read timeout in milliseconds.
589 ///
590 /// # Returns
591 ///
592 /// - `&Self` - The RequestConfig instance for chaining.
593 pub async fn ws_read_timeout_ms(&self, ws_read_timeout_ms: u64) -> &Self {
594 self.write()
595 .await
596 .set_ws_read_timeout_ms(ws_read_timeout_ms);
597 self
598 }
599}
600
601/// Provides a default value for `Request`.
602///
603/// Returns a new `Request` instance with all fields initialized to their default values.
604impl Default for Request {
605 #[inline(always)]
606 fn default() -> Self {
607 Self {
608 method: Method::default(),
609 host: String::new(),
610 version: HttpVersion::default(),
611 path: String::new(),
612 querys: hash_map_xx_hash3_64(),
613 headers: hash_map_xx_hash3_64(),
614 body: Vec::new(),
615 }
616 }
617}
618
619impl Http {
620 /// Reads the HTTP request line from the buffered reader.
621 ///
622 /// # Arguments
623 ///
624 /// - `&mut BufReader<&mut TcpStream>`: The buffered reader to read from.
625 /// - `usize`: The buffer size for initial string capacity.
626 /// - `usize`: The maximum allowed request line size.
627 ///
628 /// # Returns
629 ///
630 /// - `Result<String, RequestError>`: The request line string or an error.
631 #[inline(always)]
632 async fn check_first_line(
633 reader: &mut BufReader<&mut TcpStream>,
634 buffer_size: usize,
635 max_size: usize,
636 ) -> Result<String, RequestError> {
637 let mut line: String = String::with_capacity(buffer_size);
638 let size: usize = AsyncBufReadExt::read_line(reader, &mut line).await?;
639 if size > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_REQUEST_LINE_SIZE {
640 return Err(RequestError::RequestTooLong(HttpStatus::BadRequest));
641 }
642 Ok(line)
643 }
644
645 /// Parses the first line of HTTP request into method, path, and version components.
646 ///
647 /// # Arguments
648 ///
649 /// - `&str`: The first line string of HTTP request to parse.
650 ///
651 /// # Returns
652 ///
653 /// - `Result<(RequestMethod, &str, RequestVersion), RequestError>`: A tuple containing:
654 /// - The parsed HTTP method
655 /// - The full path string
656 /// - The parsed HTTP version
657 /// - Or an error if parsing fails
658 #[inline(always)]
659 fn parse_first_line(line: &str) -> Result<(RequestMethod, &str, RequestVersion), RequestError> {
660 let parts: Vec<&str> = line.split_whitespace().collect();
661 if parts.len() < 3 {
662 return Err(RequestError::HttpRequestPartsInsufficient(
663 HttpStatus::BadRequest,
664 ));
665 }
666 let method: RequestMethod = parts[0]
667 .parse::<RequestMethod>()
668 .unwrap_or(Method::Unknown(parts[0].to_string()));
669 let full_path: &str = parts[1];
670 let version: RequestVersion = parts[2]
671 .parse::<RequestVersion>()
672 .unwrap_or(RequestVersion::Unknown(parts[2].to_string()));
673 Ok((method, full_path, version))
674 }
675
676 /// Validates the path length against the maximum allowed size.
677 ///
678 /// # Arguments
679 ///
680 /// - `&str`: The path string to check.
681 /// - `usize`: The maximum allowed path size.
682 ///
683 /// # Returns
684 ///
685 /// - `Result<(), RequestError>`: Ok if valid, or an error if the path is too long.
686 #[inline(always)]
687 fn check_path_size(path: &str, max_size: usize) -> Result<(), RequestError> {
688 if path.len() > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_PATH_SIZE {
689 return Err(RequestError::PathTooLong(HttpStatus::URITooLong));
690 }
691 Ok(())
692 }
693
694 /// Parses the query string from the full path.
695 ///
696 /// Handles both query parameters (after `?`) and hash fragments (after `#`),
697 /// ensuring proper parsing when both are present.
698 ///
699 /// # Arguments
700 ///
701 /// - `&str`: The full path string containing the query.
702 /// - `Option<usize>`: The index of the query separator (`?`), if present.
703 /// - `Option<usize>`: The index of the hash separator (`#`), if present.
704 ///
705 /// # Returns
706 ///
707 /// - `String`: The parsed query string, or empty string if no query.
708 #[inline(always)]
709 fn parse_query(path: &str, query_index: Option<usize>, hash_index: Option<usize>) -> String {
710 query_index.map_or_else(String::new, |i: usize| {
711 let temp: &str = &path[i + 1..];
712 match hash_index {
713 None => temp.to_owned(),
714 Some(hash_idx) if hash_idx <= i => temp.to_owned(),
715 Some(hash_idx) => temp[..hash_idx - i - 1].to_owned(),
716 }
717 })
718 }
719
720 /// Validates the query string length against the maximum allowed size.
721 ///
722 /// # Arguments
723 ///
724 /// - `&str`: The query string to check.
725 /// - `usize`: The maximum allowed query size.
726 ///
727 /// # Returns
728 ///
729 /// - `Result<(), RequestError>`: Ok if valid, or an error if the query is too long.
730 #[inline(always)]
731 fn check_query_size(query: &str, max_size: usize) -> Result<(), RequestError> {
732 if query.len() > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_QUERY_SIZE {
733 return Err(RequestError::QueryTooLong(HttpStatus::URITooLong));
734 }
735 Ok(())
736 }
737
738 /// Parses the request path without query string or hash fragment.
739 ///
740 /// # Arguments
741 ///
742 /// - `&str`: The full path string.
743 /// - `RequestPath`: The owned full path for fallback.
744 /// - `Option<usize>`: The index of the query separator (`?`), if present.
745 /// - `Option<usize>`: The index of the hash separator (`#`), if present.
746 ///
747 /// # Returns
748 ///
749 /// - `RequestPath`: The request path without query or hash.
750 #[inline(always)]
751 fn parse_path(
752 path: &str,
753 query_index: Option<usize>,
754 hash_index: Option<usize>,
755 ) -> RequestPath {
756 match query_index.or(hash_index) {
757 Some(i) => path[..i].to_owned(),
758 None => path.to_owned(),
759 }
760 }
761
762 /// Parses a query string as_ref key-value pairs.
763 ///
764 /// Expects format "key1=value1&key2=value2". Empty values are allowed.
765 ///
766 /// # Arguments
767 ///
768 /// - `&str` - The query string to parse.
769 ///
770 /// # Returns
771 ///
772 /// - `RequestQuerys` - The parsed query parameters.
773 fn parse_querys(query: &str) -> RequestQuerys {
774 let mut query_map: RequestQuerys = hash_map_xx_hash3_64();
775 for pair in query.split(AND) {
776 if let Some((key, value)) = pair.split_once(EQUAL) {
777 if !key.is_empty() {
778 query_map.insert(key.to_string(), value.to_string());
779 }
780 } else if !pair.is_empty() {
781 query_map.insert(pair.to_string(), String::new());
782 }
783 }
784 query_map
785 }
786
787 /// Checks if a header line exceeds the maximum allowed length.
788 ///
789 /// # Arguments
790 ///
791 /// - `usize`: The number of bytes read for the header line.
792 /// - `usize`: The maximum allowed length for a header line.
793 ///
794 /// # Returns
795 ///
796 /// - `Result<(), RequestError>`: Returns an error if the limit is exceeded and not in low security mode.
797 #[inline(always)]
798 fn check_header_line_size(size: usize, max_size: usize) -> Result<(), RequestError> {
799 if size > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_HEADER_LINE_SIZE {
800 return Err(RequestError::HeaderLineTooLong(
801 HttpStatus::RequestHeaderFieldsTooLarge,
802 ));
803 }
804 Ok(())
805 }
806
807 /// Checks if the header count exceeds the maximum allowed.
808 ///
809 /// # Arguments
810 ///
811 /// - `usize`: The current number of headers parsed.
812 /// - `usize`: The maximum allowed number of headers.
813 ///
814 /// # Returns
815 ///
816 /// - `Result<(), RequestError>`: Returns an error if the limit is exceeded and not in low security mode.
817 #[inline(always)]
818 fn check_header_count(count: usize, max_count: usize) -> Result<(), RequestError> {
819 if count > max_count && max_count != DEFAULT_LOW_SECURITY_MAX_HEADER_COUNT {
820 return Err(RequestError::TooManyHeaders(
821 HttpStatus::RequestHeaderFieldsTooLarge,
822 ));
823 }
824 Ok(())
825 }
826
827 /// Checks if a header key exceeds the maximum allowed length.
828 ///
829 /// # Arguments
830 ///
831 /// - `&str`: The header key to check.
832 /// - `usize`: The maximum allowed length for a header key.
833 ///
834 /// # Returns
835 ///
836 /// - `Result<(), RequestError>`: Returns an error if the limit is exceeded and not in low security mode.
837 #[inline(always)]
838 fn check_header_key_size(key: &str, max_size: usize) -> Result<(), RequestError> {
839 if key.len() > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_HEADER_KEY_SIZE {
840 return Err(RequestError::HeaderKeyTooLong(
841 HttpStatus::RequestHeaderFieldsTooLarge,
842 ));
843 }
844 Ok(())
845 }
846
847 /// Checks if a header value exceeds the maximum allowed length.
848 ///
849 /// # Arguments
850 ///
851 /// - `&str`: The header value to check.
852 /// - `usize`: The maximum allowed length for a header value.
853 ///
854 /// # Returns
855 ///
856 /// - `Result<(), RequestError>`: Returns an error if the limit is exceeded and not in low security mode.
857 #[inline(always)]
858 fn check_header_value_size(value: &str, max_size: usize) -> Result<(), RequestError> {
859 if value.len() > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_HEADER_VALUE_SIZE {
860 return Err(RequestError::HeaderValueTooLong(
861 HttpStatus::RequestHeaderFieldsTooLarge,
862 ));
863 }
864 Ok(())
865 }
866
867 /// Parses the Content-Length header value and checks it against max body size.
868 ///
869 /// # Arguments
870 ///
871 /// - `&str`: The Content-Length header value string.
872 /// - `usize`: The maximum allowed body size.
873 ///
874 /// # Returns
875 ///
876 /// - `Result<usize, RequestError>`: The parsed content length or an error.
877 #[inline(always)]
878 fn check_body_size(value: &str, max_size: usize) -> Result<usize, RequestError> {
879 let length: usize = value.parse::<usize>()?;
880 if length > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_BODY_SIZE {
881 return Err(RequestError::ContentLengthTooLarge(
882 HttpStatus::PayloadTooLarge,
883 ));
884 }
885 Ok(length)
886 }
887
888 /// Parses HTTP headers from a buffered reader.
889 ///
890 /// This method reads header lines from the provided buffered reader until an empty line
891 /// is encountered, which indicates the end of headers. It checks header count, length,
892 /// and content according to the provided configuration.
893 ///
894 /// # Arguments
895 ///
896 /// - `&mut AsyncBufReadExt + Unpin`: A mutable reference to a buffered reader implementing `AsyncBufReadExt`.
897 /// - `&RequestConfigData`: Configuration for security limits and buffer settings.
898 ///
899 /// # Returns
900 ///
901 /// - `Result<(RequestHeaders, RequestHost, usize), RequestError>`: A tuple containing:
902 /// - The parsed headers as a hash map
903 /// - The host value parsed from the Host header
904 /// - The content length parsed from the Content-Length header
905 /// - Or an error if parsing fails
906 async fn parse_headers<R>(
907 reader: &mut R,
908 config: &RequestConfigData,
909 ) -> Result<(RequestHeaders, RequestHost, usize), RequestError>
910 where
911 R: AsyncBufReadExt + Unpin,
912 {
913 let buffer_size: usize = config.get_buffer_size();
914 let max_header_line_size: usize = config.get_max_header_line_size();
915 let max_header_count: usize = config.get_max_header_count();
916 let max_header_key_size: usize = config.get_max_header_key_size();
917 let max_header_value_size: usize = config.get_max_header_value_size();
918 let max_body_size: usize = config.get_max_body_size();
919 let mut headers: RequestHeaders = hash_map_xx_hash3_64();
920 let mut host: RequestHost = String::new();
921 let mut content_size: usize = 0;
922 let mut header_count: usize = 0;
923 loop {
924 let header_line: &mut String = &mut String::with_capacity(buffer_size);
925 let bytes_read: usize = AsyncBufReadExt::read_line(reader, header_line).await?;
926 Self::check_header_line_size(bytes_read, max_header_line_size)?;
927 let header_line: &str = header_line.trim();
928 if header_line.is_empty() {
929 break;
930 }
931 header_count += 1;
932 Self::check_header_count(header_count, max_header_count)?;
933 let (key_part, value_part): (&str, &str) = match header_line.split_once(COLON) {
934 Some(parts) => parts,
935 None => continue,
936 };
937 let key: String = key_part.trim().to_ascii_lowercase();
938 if key.is_empty() {
939 continue;
940 }
941 Self::check_header_key_size(&key, max_header_key_size)?;
942 let value: String = value_part.trim().to_string();
943 Self::check_header_value_size(&value, max_header_value_size)?;
944 match key.as_str() {
945 HOST => host = value.clone(),
946 CONTENT_LENGTH => {
947 content_size = Self::check_body_size(&value, max_body_size)?;
948 }
949 _ => {}
950 }
951 headers.entry(key).or_default().push_back(value);
952 }
953 Ok((headers, host, content_size))
954 }
955
956 /// Reads the request body from the buffered reader.
957 ///
958 /// # Arguments
959 ///
960 /// - `&mut BufReader<&mut TcpStream>`: The buffered reader to read from.
961 /// - `usize`: The expected content size.
962 ///
963 /// # Returns
964 ///
965 /// - `Result<RequestBody, RequestError>`: The body bytes or an error.
966 #[inline(always)]
967 async fn parse_body(
968 reader: &mut BufReader<&mut TcpStream>,
969 content_size: usize,
970 ) -> Result<RequestBody, RequestError> {
971 let mut body: RequestBody = Vec::with_capacity(content_size);
972 if content_size > 0 {
973 body.resize(content_size, 0);
974 AsyncReadExt::read_exact(reader, &mut body).await?;
975 }
976 Ok(body)
977 }
978
979 /// Parses the HTTP request content from the stream.
980 ///
981 /// This is an internal helper function that performs the actual parsing.
982 ///
983 /// # Arguments
984 ///
985 /// - `&ArcRwLock<TcpStream>`: The TCP stream to read from.
986 /// - `&RequestConfigData`: Configuration for security limits and buffer settings.
987 ///
988 /// # Returns
989 ///
990 /// - `Result<Request, RequestError>`: The parsed request or an error.
991 async fn parse_from_stream(
992 stream: &ArcRwLockStream,
993 config: &RequestConfigData,
994 ) -> Result<Request, RequestError> {
995 let buffer_size: usize = config.get_buffer_size();
996 let max_request_line_size: usize = config.get_max_request_line_size();
997 let max_path_size: usize = config.get_max_path_size();
998 let max_query_size: usize = config.get_max_query_size();
999 let mut buf_stream: RwLockWriteGuard<'_, TcpStream> = stream.write().await;
1000 let reader: &mut BufReader<&mut TcpStream> =
1001 &mut BufReader::with_capacity(buffer_size, &mut buf_stream);
1002 let line: String =
1003 Self::check_first_line(reader, buffer_size, max_request_line_size).await?;
1004 let (method, path, version): (RequestMethod, &str, RequestVersion) =
1005 Self::parse_first_line(&line)?;
1006 Self::check_path_size(path, max_path_size)?;
1007 let hash_index: Option<usize> = path.find(HASH);
1008 let query_index: Option<usize> = path.find(QUERY);
1009 let query_string: String = Self::parse_query(path, query_index, hash_index);
1010 Self::check_query_size(&query_string, max_query_size)?;
1011 let querys: RequestQuerys = Self::parse_querys(&query_string);
1012 let path: RequestPath = Self::parse_path(path, query_index, hash_index);
1013 let (headers, host, content_size): (RequestHeaders, RequestHost, usize) =
1014 Self::parse_headers(reader, config).await?;
1015 let body: RequestBody = Self::parse_body(reader, content_size).await?;
1016 Ok(Request {
1017 method,
1018 host,
1019 version,
1020 path,
1021 querys,
1022 headers,
1023 body,
1024 })
1025 }
1026}
1027
1028impl Ws {
1029 /// Checks if the WebSocket frame count exceeds the maximum allowed.
1030 ///
1031 /// # Arguments
1032 ///
1033 /// - `usize`: The current number of frames.
1034 /// - `usize`: The maximum allowed number of frames.
1035 ///
1036 /// # Returns
1037 ///
1038 /// - `Result<(), RequestError>`: Returns an error if the limit is exceeded and not in low security mode.
1039 #[inline(always)]
1040 fn check_frame_count(count: usize, max_count: usize) -> Result<(), RequestError> {
1041 if count > max_count && max_count != DEFAULT_LOW_SECURITY_MAX_WS_FRAMES_COUNT {
1042 return Err(RequestError::TooManyHeaders(
1043 HttpStatus::RequestHeaderFieldsTooLarge,
1044 ));
1045 }
1046 Ok(())
1047 }
1048
1049 /// Reads data from the stream with optional timeout handling.
1050 ///
1051 /// # Arguments
1052 ///
1053 /// - `&ArcRwLockStream`: The TCP stream to read from.
1054 /// - `&mut [u8]`: The buffer to read data into.
1055 /// - `Option<Duration>`: The optional timeout duration. If Some, timeout is applied; if None, no timeout.
1056 /// - `&mut bool`: Mutable reference to track if we got a client response.
1057 ///
1058 /// # Returns
1059 ///
1060 /// - `Result<Option<usize>, RequestError>`: The number of bytes read, None for timeout/ping, or an error.
1061 async fn read(
1062 stream: &ArcRwLockStream,
1063 buffer: &mut [u8],
1064 duration_opt: Option<Duration>,
1065 is_client_response: &mut bool,
1066 ) -> Result<Option<usize>, RequestError> {
1067 if let Some(duration) = duration_opt {
1068 return match timeout(duration, stream.write().await.read(buffer)).await {
1069 Ok(result) => match result {
1070 Ok(len) => Ok(Some(len)),
1071 Err(error) => Err(error.into()),
1072 },
1073 Err(error) => {
1074 if !*is_client_response {
1075 return Err(error.into());
1076 }
1077 *is_client_response = false;
1078 stream.try_send_body(&PING_FRAME).await?;
1079 Ok(None)
1080 }
1081 };
1082 }
1083 match stream.write().await.read(buffer).await {
1084 Ok(len) => Ok(Some(len)),
1085 Err(error) => Err(error.into()),
1086 }
1087 }
1088
1089 /// Handles a decoded WebSocket Text or Binary frame and accumulates payload data.
1090 ///
1091 /// # Arguments
1092 ///
1093 /// - `&Request`: The request to update on completion.
1094 /// - `&WebSocketFrame`: The decoded WebSocket frame.
1095 /// - `&mut Vec<u8>`: The accumulated frame data.
1096 /// - `usize`: Maximum allowed frame size.
1097 ///
1098 /// # Returns
1099 ///
1100 /// - `Result<Option<Request>, RequestError>`: Some(request) if frame is complete, None to continue, or error.
1101 #[inline(always)]
1102 fn parse_frame(
1103 request: &Request,
1104 frame: &WebSocketFrame,
1105 full_frame: &mut Vec<u8>,
1106 max_size: usize,
1107 ) -> Result<Option<Request>, RequestError> {
1108 let payload_data: &[u8] = frame.get_payload_data();
1109 let payload_data_len: usize = payload_data.len();
1110 if payload_data_len > max_size {
1111 return Err(RequestError::WebSocketFrameTooLarge(
1112 HttpStatus::PayloadTooLarge,
1113 ));
1114 }
1115 let sum_len: usize = full_frame.len() + payload_data_len;
1116 if sum_len > max_size && max_size != DEFAULT_LOW_SECURITY_MAX_WS_FRAME_SIZE {
1117 return Err(RequestError::WebSocketFrameTooLarge(
1118 HttpStatus::PayloadTooLarge,
1119 ));
1120 }
1121 full_frame.extend_from_slice(payload_data);
1122 if *frame.get_fin() {
1123 let mut result: Request = request.clone();
1124 result.body = full_frame.clone();
1125 return Ok(Some(result));
1126 }
1127 Ok(None)
1128 }
1129}
1130
1131impl Request {
1132 /// Parses an HTTP request from a TCP stream.
1133 ///
1134 /// Wraps the stream in a buffered reader and delegates to `http_from_reader`.
1135 /// If the timeout is DEFAULT_LOW_SECURITY_HTTP_READ_TIMEOUT_MS, no timeout is applied.
1136 ///
1137 /// # Arguments
1138 ///
1139 /// - `&ArcRwLock<TcpStream>` - The TCP stream to read from.
1140 /// - `&RequestConfigData` - Configuration for security limits and buffer settings.
1141 ///
1142 /// # Returns
1143 ///
1144 /// - `Result<Request, RequestError>` - The parsed request or an error.
1145 pub async fn http_from_stream(
1146 stream: &ArcRwLockStream,
1147 config: &RequestConfigData,
1148 ) -> Result<Request, RequestError> {
1149 let timeout_ms: u64 = config.get_http_read_timeout_ms();
1150 if timeout_ms == DEFAULT_LOW_SECURITY_HTTP_READ_TIMEOUT_MS {
1151 return Http::parse_from_stream(stream, config).await;
1152 }
1153 let duration: Duration = Duration::from_millis(timeout_ms);
1154 timeout(duration, Http::parse_from_stream(stream, config)).await?
1155 }
1156
1157 /// Parses a WebSocket request from a TCP stream.
1158 ///
1159 /// Wraps the stream in a buffered reader and delegates to `ws_from_reader`.
1160 /// If the timeout is DEFAULT_LOW_SECURITY_WS_READ_TIMEOUT_MS, no timeout is applied.
1161 ///
1162 /// # Arguments
1163 ///
1164 /// - `&ArcRwLock<TcpStream>`: The TCP stream to read from.
1165 /// - `&RequestConfigData`: Configuration for security limits and buffer settings.
1166 ///
1167 /// # Returns
1168 ///
1169 /// - `Result<Request, RequestError>`: The parsed WebSocket request or an error.
1170 pub async fn ws_from_stream(
1171 &self,
1172 stream: &ArcRwLockStream,
1173 config: &RequestConfigData,
1174 ) -> Result<Request, RequestError> {
1175 let buffer_size: usize = config.get_buffer_size();
1176 let max_ws_frame_size: usize = config.get_max_ws_frame_size();
1177 let ws_read_timeout_ms: u64 = config.get_ws_read_timeout_ms();
1178 let max_ws_frames_count: usize = config.get_max_ws_frames_count();
1179 let mut dynamic_buffer: Vec<u8> = Vec::with_capacity(buffer_size);
1180 let mut temp_buffer: Vec<u8> = vec![0; buffer_size];
1181 let mut full_frame: Vec<u8> = Vec::with_capacity(max_ws_frame_size);
1182 let mut frame_count: usize = 0;
1183 let mut is_client_response: bool = false;
1184 let duration_opt: Option<Duration> =
1185 if ws_read_timeout_ms == DEFAULT_LOW_SECURITY_WS_READ_TIMEOUT_MS {
1186 None
1187 } else {
1188 let adjusted_timeout_ms: u64 = (ws_read_timeout_ms >> 1) + (ws_read_timeout_ms & 1);
1189 Some(Duration::from_millis(adjusted_timeout_ms))
1190 };
1191 loop {
1192 let len: usize = match Ws::read(
1193 stream,
1194 &mut temp_buffer,
1195 duration_opt,
1196 &mut is_client_response,
1197 )
1198 .await
1199 {
1200 Ok(Some(len)) => len,
1201 Ok(None) => continue,
1202 Err(error) => return Err(error),
1203 };
1204 if len == 0 {
1205 return Err(RequestError::IncompleteWebSocketFrame(
1206 HttpStatus::BadRequest,
1207 ));
1208 }
1209 dynamic_buffer.extend_from_slice(&temp_buffer[..len]);
1210 while let Some((frame, consumed)) = WebSocketFrame::decode_ws_frame(&dynamic_buffer) {
1211 is_client_response = true;
1212 dynamic_buffer.drain(0..consumed);
1213 frame_count += 1;
1214 Ws::check_frame_count(frame_count, max_ws_frames_count)?;
1215 match frame.get_opcode() {
1216 WebSocketOpcode::Close => {
1217 return Err(RequestError::ClientClosedConnection(HttpStatus::BadRequest));
1218 }
1219 WebSocketOpcode::Ping | WebSocketOpcode::Pong => continue,
1220 WebSocketOpcode::Text | WebSocketOpcode::Binary => {
1221 match Ws::parse_frame(self, &frame, &mut full_frame, max_ws_frame_size) {
1222 Ok(Some(result)) => return Ok(result),
1223 Ok(None) => continue,
1224 Err(error) => return Err(error),
1225 }
1226 }
1227 _ => {
1228 return Err(RequestError::WebSocketOpcodeUnsupported(
1229 HttpStatus::NotImplemented,
1230 ));
1231 }
1232 }
1233 }
1234 }
1235 }
1236
1237 /// Tries to get a query parameter value by key.
1238 ///
1239 /// The key type must implement AsRef<str> conversion.
1240 ///
1241 /// # Arguments
1242 ///
1243 /// - `AsRef<str>` - The query parameter key (implements AsRef<str>).
1244 ///
1245 /// # Returns
1246 ///
1247 /// - `Option<RequestQuerysValue>` - The parameter value if exists.
1248 #[inline(always)]
1249 pub fn try_get_query<K>(&self, key: K) -> Option<RequestQuerysValue>
1250 where
1251 K: AsRef<str>,
1252 {
1253 self.querys.get(key.as_ref()).cloned()
1254 }
1255
1256 /// Gets a query parameter value by key.
1257 ///
1258 /// The key type must implement AsRef<str> conversion.
1259 ///
1260 /// # Arguments
1261 ///
1262 /// - `AsRef<str>` - The query parameter key (implements AsRef<str>).
1263 ///
1264 /// # Returns
1265 ///
1266 /// - `RequestQuerysValue` - The parameter value if exists.
1267 ///
1268 /// # Panics
1269 ///
1270 /// This function will panic if the query parameter key is not found.
1271 #[inline(always)]
1272 pub fn get_query<K>(&self, key: K) -> RequestQuerysValue
1273 where
1274 K: AsRef<str>,
1275 {
1276 self.try_get_query(key).unwrap()
1277 }
1278
1279 /// Tries to retrieve the value of a request header by its key.
1280 ///
1281 /// # Arguments
1282 ///
1283 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
1284 ///
1285 /// # Returns
1286 ///
1287 /// - `Option<RequestHeadersValue>` - The optional header values.
1288 #[inline(always)]
1289 pub fn try_get_header<K>(&self, key: K) -> Option<RequestHeadersValue>
1290 where
1291 K: AsRef<str>,
1292 {
1293 self.headers.get(key.as_ref()).cloned()
1294 }
1295
1296 /// Retrieves the value of a request header by its key.
1297 ///
1298 /// # Arguments
1299 ///
1300 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
1301 ///
1302 /// # Returns
1303 ///
1304 /// - `RequestHeadersValue` - The optional header values.
1305 ///
1306 /// # Panics
1307 ///
1308 /// This function will panic if the header key is not found.
1309 #[inline(always)]
1310 pub fn get_header<K>(&self, key: K) -> RequestHeadersValue
1311 where
1312 K: AsRef<str>,
1313 {
1314 self.try_get_header(key).unwrap()
1315 }
1316
1317 /// Tries to retrieve the first value of a request header by its key.
1318 ///
1319 /// # Arguments
1320 ///
1321 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
1322 ///
1323 /// # Returns
1324 ///
1325 /// - `Option<RequestHeadersValueItem>` - The first header value if exists.
1326 #[inline(always)]
1327 pub fn try_get_header_front<K>(&self, key: K) -> Option<RequestHeadersValueItem>
1328 where
1329 K: AsRef<str>,
1330 {
1331 self.headers
1332 .get(key.as_ref())
1333 .and_then(|values| values.front().cloned())
1334 }
1335
1336 /// Retrieves the first value of a request header by its key.
1337 ///
1338 /// # Arguments
1339 ///
1340 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
1341 ///
1342 /// # Returns
1343 ///
1344 /// - `RequestHeadersValueItem` - The first header value if exists.
1345 ///
1346 /// # Panics
1347 ///
1348 /// This function will panic if the header key is not found.
1349 #[inline(always)]
1350 pub fn get_header_front<K>(&self, key: K) -> RequestHeadersValueItem
1351 where
1352 K: AsRef<str>,
1353 {
1354 self.try_get_header_front(key).unwrap()
1355 }
1356
1357 /// Tries to retrieve the last value of a request header by its key.
1358 ///
1359 /// # Arguments
1360 ///
1361 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
1362 ///
1363 /// # Returns
1364 ///
1365 /// - `Option<RequestHeadersValueItem>` - The last header value if exists.
1366 #[inline(always)]
1367 pub fn try_get_header_back<K>(&self, key: K) -> Option<RequestHeadersValueItem>
1368 where
1369 K: AsRef<str>,
1370 {
1371 self.headers
1372 .get(key.as_ref())
1373 .and_then(|values| values.back().cloned())
1374 }
1375
1376 /// Retrieves the last value of a request header by its key.
1377 ///
1378 /// # Arguments
1379 ///
1380 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
1381 ///
1382 /// # Returns
1383 ///
1384 /// - `RequestHeadersValueItem` - The last header value if exists.
1385 ///
1386 /// # Panics
1387 ///
1388 /// This function will panic if the header key is not found.
1389 #[inline(always)]
1390 pub fn get_header_back<K>(&self, key: K) -> RequestHeadersValueItem
1391 where
1392 K: AsRef<str>,
1393 {
1394 self.try_get_header_back(key).unwrap()
1395 }
1396
1397 /// Tries to retrieve the number of values for a specific header.
1398 ///
1399 /// # Arguments
1400 ///
1401 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
1402 ///
1403 /// # Returns
1404 ///
1405 /// - `Option<usize>` - The count of values for the header if exists.
1406 #[inline(always)]
1407 pub fn try_get_header_size<K>(&self, key: K) -> Option<usize>
1408 where
1409 K: AsRef<str>,
1410 {
1411 self.headers.get(key.as_ref()).map(|values| values.len())
1412 }
1413
1414 /// Retrieves the number of values for a specific header.
1415 ///
1416 /// # Arguments
1417 ///
1418 /// - `AsRef<str>` - The header's key (must implement AsRef<str>).
1419 ///
1420 /// # Returns
1421 ///
1422 /// - `usize` - The count of values for the header.
1423 ///
1424 /// # Panics
1425 ///
1426 /// This function will panic if the header key is not found.
1427 #[inline(always)]
1428 pub fn get_header_size<K>(&self, key: K) -> usize
1429 where
1430 K: AsRef<str>,
1431 {
1432 self.try_get_header_size(key).unwrap()
1433 }
1434
1435 /// Retrieves the total number of header values across all headers.
1436 ///
1437 /// # Returns
1438 ///
1439 /// - `usize` - The total count of all header values.
1440 #[inline(always)]
1441 pub fn get_headers_values_size(&self) -> usize {
1442 self.headers.values().map(|values| values.len()).sum()
1443 }
1444
1445 /// Retrieves the number of unique headers.
1446 ///
1447 /// # Returns
1448 ///
1449 /// - `usize` - The count of unique header keys.
1450 #[inline(always)]
1451 pub fn get_headers_size(&self) -> usize {
1452 self.headers.len()
1453 }
1454
1455 /// Checks if a specific header exists.
1456 ///
1457 /// # Arguments
1458 ///
1459 /// - `AsRef<str>` - The header key to check (must implement AsRef<str>).
1460 ///
1461 /// # Returns
1462 ///
1463 /// - `bool` - Whether the header exists.
1464 #[inline(always)]
1465 pub fn has_header<K>(&self, key: K) -> bool
1466 where
1467 K: AsRef<str>,
1468 {
1469 self.headers.contains_key(key.as_ref())
1470 }
1471
1472 /// Checks if a header contains a specific value.
1473 ///
1474 /// # Arguments
1475 ///
1476 /// - `AsRef<str>` - The header key to check (must implement AsRef<str>).
1477 /// - `AsRef<str>` - The value to search for (must implement AsRef<str>).
1478 ///
1479 /// # Returns
1480 ///
1481 /// - `bool` - Whether the header contains the value.
1482 #[inline(always)]
1483 pub fn has_header_value<K, V>(&self, key: K, value: V) -> bool
1484 where
1485 K: AsRef<str>,
1486 V: AsRef<str>,
1487 {
1488 if let Some(values) = self.headers.get(key.as_ref()) {
1489 values.contains(&value.as_ref().to_owned())
1490 } else {
1491 false
1492 }
1493 }
1494
1495 /// Retrieves the upgrade type from the request headers.
1496 ///
1497 /// This method looks for the `UPGRADE` header and attempts to parse its value
1498 /// as_ref an `UpgradeType`. If the header is missing or the value is invalid,
1499 /// it returns the default `UpgradeType`.
1500 ///
1501 /// # Returns
1502 ///
1503 /// - `UpgradeType` - The parsed upgrade type.
1504 #[inline(always)]
1505 pub fn get_upgrade_type(&self) -> UpgradeType {
1506 let upgrade_type: UpgradeType = self
1507 .try_get_header_back(UPGRADE)
1508 .and_then(|data| data.parse::<UpgradeType>().ok())
1509 .unwrap_or_default();
1510 upgrade_type
1511 }
1512
1513 /// Retrieves the body content of the request as a UTF-8 encoded string.
1514 ///
1515 /// This method uses `String::from_utf8_lossy` to convert the byte slice returned by `self.get_body()` as_ref a string.
1516 /// If the byte slice contains invalid UTF-8 sequences, they will be replaced with the Unicode replacement character ().
1517 ///
1518 /// # Returns
1519 ///
1520 /// - `String` - The body content as a string.
1521 #[inline(always)]
1522 pub fn get_body_string(&self) -> String {
1523 String::from_utf8_lossy(self.get_body()).into_owned()
1524 }
1525
1526 /// Deserializes the body content of the request as_ref a specified type `T`.
1527 ///
1528 /// This method first retrieves the body content as a byte slice using `self.get_body()`.
1529 /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
1530 ///
1531 /// # Arguments
1532 ///
1533 /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
1534 ///
1535 /// # Returns
1536 ///
1537 /// - `Result<T, serde_json::Error>` - The deserialization result.
1538 pub fn try_get_body_json<T>(&self) -> Result<T, serde_json::Error>
1539 where
1540 T: DeserializeOwned,
1541 {
1542 serde_json::from_slice(self.get_body())
1543 }
1544
1545 /// Deserializes the body content of the request as_ref a specified type `T`.
1546 ///
1547 /// This method first retrieves the body content as a byte slice using `self.get_body()`.
1548 /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
1549 ///
1550 /// # Arguments
1551 ///
1552 /// - `DeserializeOwned` - The target type to deserialize as_ref (must implement DeserializeOwned).
1553 ///
1554 /// # Returns
1555 ///
1556 /// - `T` - The deserialized body content.
1557 ///
1558 /// # Panics
1559 ///
1560 /// This function will panic if the deserialization fails.
1561 pub fn get_body_json<T>(&self) -> T
1562 where
1563 T: DeserializeOwned,
1564 {
1565 self.try_get_body_json().unwrap()
1566 }
1567
1568 /// Checks whether the request method is GET.
1569 ///
1570 /// # Returns
1571 ///
1572 /// - `bool` - Whether the method is GET.
1573 #[inline(always)]
1574 pub fn is_get_method(&self) -> bool {
1575 self.get_method().is_get()
1576 }
1577
1578 /// Checks whether the request method is POST.
1579 ///
1580 /// # Returns
1581 ///
1582 /// - `bool` - Whether the method is POST.
1583 #[inline(always)]
1584 pub fn is_post_method(&self) -> bool {
1585 self.get_method().is_post()
1586 }
1587
1588 /// Checks whether the request method is PUT.
1589 ///
1590 /// # Returns
1591 ///
1592 /// - `bool` - Whether the method is PUT.
1593 #[inline(always)]
1594 pub fn is_put_method(&self) -> bool {
1595 self.get_method().is_put()
1596 }
1597
1598 /// Checks whether the request method is DELETE.
1599 ///
1600 /// # Returns
1601 ///
1602 /// - `bool` - Whether the method is DELETE.
1603 #[inline(always)]
1604 pub fn is_delete_method(&self) -> bool {
1605 self.get_method().is_delete()
1606 }
1607
1608 /// Checks whether the request method is PATCH.
1609 ///
1610 /// # Returns
1611 ///
1612 /// - `bool` - Whether the method is PATCH.
1613 #[inline(always)]
1614 pub fn is_patch_method(&self) -> bool {
1615 self.get_method().is_patch()
1616 }
1617
1618 /// Checks whether the request method is HEAD.
1619 ///
1620 /// # Returns
1621 ///
1622 /// - `bool` - Whether the method is HEAD.
1623 #[inline(always)]
1624 pub fn is_head_method(&self) -> bool {
1625 self.get_method().is_head()
1626 }
1627
1628 /// Checks whether the request method is OPTIONS.
1629 ///
1630 /// # Returns
1631 ///
1632 /// - `bool` - Whether the method is OPTIONS.
1633 #[inline(always)]
1634 pub fn is_options_method(&self) -> bool {
1635 self.get_method().is_options()
1636 }
1637
1638 /// Checks whether the request method is CONNECT.
1639 ///
1640 /// # Returns
1641 ///
1642 /// - `bool` - Whether the method is CONNECT.
1643 #[inline(always)]
1644 pub fn is_connect_method(&self) -> bool {
1645 self.get_method().is_connect()
1646 }
1647
1648 /// Checks whether the request method is TRACE.
1649 ///
1650 /// # Returns
1651 ///
1652 /// - `bool` - Whether the method is TRACE.
1653 #[inline(always)]
1654 pub fn is_trace_method(&self) -> bool {
1655 self.get_method().is_trace()
1656 }
1657
1658 /// Checks whether the request method is UNKNOWN.
1659 ///
1660 /// # Returns
1661 ///
1662 /// - `bool` - Whether the method is UNKNOWN.
1663 #[inline(always)]
1664 pub fn is_unknown_method(&self) -> bool {
1665 self.get_method().is_unknown()
1666 }
1667
1668 /// Checks whether the HTTP version is HTTP/0.9.
1669 ///
1670 /// # Returns
1671 ///
1672 /// - `bool` - Whether the version is HTTP/0.9.
1673 #[inline(always)]
1674 pub fn is_http0_9_version(&self) -> bool {
1675 self.get_version().is_http0_9()
1676 }
1677
1678 /// Checks whether the HTTP version is HTTP/1.0.
1679 ///
1680 /// # Returns
1681 ///
1682 /// - `bool` - Whether the version is HTTP/1.0.
1683 #[inline(always)]
1684 pub fn is_http1_0_version(&self) -> bool {
1685 self.get_version().is_http1_0()
1686 }
1687
1688 /// Checks whether the HTTP version is HTTP/1.1.
1689 ///
1690 /// # Returns
1691 ///
1692 /// - `bool` - Whether the version is HTTP/1.1.
1693 #[inline(always)]
1694 pub fn is_http1_1_version(&self) -> bool {
1695 self.get_version().is_http1_1()
1696 }
1697
1698 /// Checks whether the HTTP version is HTTP/2.
1699 ///
1700 /// # Returns
1701 ///
1702 /// - `bool` - Whether the version is HTTP/2.
1703 #[inline(always)]
1704 pub fn is_http2_version(&self) -> bool {
1705 self.get_version().is_http2()
1706 }
1707
1708 /// Checks whether the HTTP version is HTTP/3.
1709 ///
1710 /// # Returns
1711 ///
1712 /// - `bool` - Whether the version is HTTP/3.
1713 #[inline(always)]
1714 pub fn is_http3_version(&self) -> bool {
1715 self.get_version().is_http3()
1716 }
1717
1718 /// Checks if the HTTP version is HTTP/1.1 or higher.
1719 ///
1720 /// # Returns
1721 ///
1722 /// - `bool` - Whether the version is HTTP/1.1 or higher.
1723 #[inline(always)]
1724 pub fn is_http1_1_or_higher_version(&self) -> bool {
1725 self.get_version().is_http1_1_or_higher()
1726 }
1727
1728 /// Checks whether the version belongs to the HTTP family.
1729 ///
1730 /// # Returns
1731 ///
1732 /// - `bool` - Whether the version is HTTP.
1733 #[inline(always)]
1734 pub fn is_http_version(&self) -> bool {
1735 self.get_version().is_http()
1736 }
1737
1738 /// Checks whether the HTTP version is unknown.
1739 ///
1740 /// # Returns
1741 ///
1742 /// - `bool` - Whether the version is unknown.
1743 #[inline(always)]
1744 pub fn is_unknown_version(&self) -> bool {
1745 self.get_version().is_unknown()
1746 }
1747
1748 /// Checks whether the WebSocket upgrade is enabled for this request.
1749 ///
1750 /// This method determines if the `UPGRADE` header indicates a WebSocket connection.
1751 ///
1752 /// # Returns
1753 ///
1754 /// - `bool` - Whether WebSocket upgrade is enabled.
1755 #[inline(always)]
1756 pub fn is_ws_upgrade_type(&self) -> bool {
1757 self.get_upgrade_type().is_ws()
1758 }
1759
1760 /// Checks if the current upgrade type is HTTP/2 cleartext (h2c).
1761 ///
1762 /// # Returns
1763 ///
1764 /// - `bool` - Whether the upgrade type is h2c.
1765 #[inline(always)]
1766 pub fn is_h2c_upgrade_type(&self) -> bool {
1767 self.get_upgrade_type().is_h2c()
1768 }
1769
1770 /// Checks if the current upgrade type is TLS (any version).
1771 ///
1772 /// # Returns
1773 ///
1774 /// - `bool` - Whether the upgrade type is TLS.
1775 #[inline(always)]
1776 pub fn is_tls_upgrade_type(&self) -> bool {
1777 self.get_upgrade_type().is_tls()
1778 }
1779
1780 /// Checks whether the upgrade type is unknown.
1781 ///
1782 /// # Returns
1783 ///
1784 /// - `bool` - Whether the upgrade type is unknown.
1785 #[inline(always)]
1786 pub fn is_unknown_upgrade_type(&self) -> bool {
1787 self.get_upgrade_type().is_unknown()
1788 }
1789
1790 /// Determines if a keep-alive connection should be enabled for this request.
1791 ///
1792 /// This function checks the `Connection` header and the HTTP version to determine
1793 /// if keep-alive should be enabled. The logic is as follows:
1794 ///
1795 /// 1. If the `Connection` header exists:
1796 /// - Returns `true` if the header value is "keep-alive" (case-insensitive).
1797 /// - Returns `false` if the header value is "close" (case-insensitive).
1798 /// 2. If no `Connection` header is present:
1799 /// - Returns `true` if the HTTP version is 1.1 or higher.
1800 /// - Returns `false` otherwise.
1801 ///
1802 /// # Returns
1803 ///
1804 /// - `bool` - Whether keep-alive should be enabled.
1805 #[inline(always)]
1806 pub fn is_enable_keep_alive(&self) -> bool {
1807 if let Some(connection_value) = self.try_get_header_back(CONNECTION) {
1808 if connection_value.eq_ignore_ascii_case(KEEP_ALIVE) {
1809 return true;
1810 } else if connection_value.eq_ignore_ascii_case(CLOSE) {
1811 return self.is_ws_upgrade_type();
1812 }
1813 }
1814 self.is_http1_1_or_higher_version() || self.is_ws_upgrade_type()
1815 }
1816
1817 /// Determines if keep-alive should be disabled for this request.
1818 ///
1819 /// # Returns
1820 ///
1821 /// - `bool` - Whether keep-alive should be disabled.
1822 #[inline(always)]
1823 pub fn is_disable_keep_alive(&self) -> bool {
1824 !self.is_enable_keep_alive()
1825 }
1826
1827 /// Serializes the request to a JSON byte vector.
1828 ///
1829 /// This method attempts to serialize the entire request structure into a JSON
1830 /// formatted byte vector representation.
1831 ///
1832 /// # Returns
1833 ///
1834 /// - `Result<Vec<u8>, serde_json::Error>` - The serialized JSON bytes on success,
1835 /// or a serialization error on failure.
1836 #[inline(always)]
1837 pub fn try_json_vec(&self) -> Result<Vec<u8>, serde_json::Error> {
1838 serde_json::to_vec(self)
1839 }
1840
1841 /// Serializes the request to a JSON byte vector.
1842 ///
1843 /// This method serializes the entire request structure into a JSON formatted
1844 /// byte vector representation.
1845 ///
1846 /// # Returns
1847 ///
1848 /// - `Vec<u8>` - The serialized JSON bytes.
1849 ///
1850 /// # Panics
1851 ///
1852 /// This function will panic if the serialization fails.
1853 #[inline(always)]
1854 pub fn json_vec(&self) -> Vec<u8> {
1855 self.try_json_vec().unwrap()
1856 }
1857
1858 /// Serializes the request to a JSON string.
1859 ///
1860 /// This method attempts to serialize the entire request structure into a JSON
1861 /// formatted string representation.
1862 ///
1863 /// # Returns
1864 ///
1865 /// - `Result<String, serde_json::Error>` - The serialized JSON string on success,
1866 /// or a serialization error on failure.
1867 #[inline(always)]
1868 pub fn try_json_string(&self) -> Result<String, serde_json::Error> {
1869 serde_json::to_string(self)
1870 }
1871
1872 /// Serializes the request to a JSON string.
1873 ///
1874 /// This method serializes the entire request structure into a JSON formatted
1875 /// string representation.
1876 ///
1877 /// # Returns
1878 ///
1879 /// - `String` - The serialized JSON string.
1880 ///
1881 /// # Panics
1882 ///
1883 /// This function will panic if the serialization fails.
1884 #[inline(always)]
1885 pub fn json_string(&self) -> String {
1886 self.try_json_string().unwrap()
1887 }
1888}