1use crate::*;
2
3impl std::error::Error for RequestError {}
5
6impl Default for RequestError {
8 fn default() -> Self {
12 RequestError::Unknown(HttpStatus::InternalServerError)
13 }
14}
15
16impl Display for RequestError {
18 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19 match self {
20 Self::HttpRead(status) => write!(f, "Http read error [{}]", status.code()),
21 Self::GetTcpStream(status) => write!(f, "Failed to get tcp stream [{}]", status.code()),
22 Self::GetTlsStream(status) => write!(f, "Failed to get tls stream [{}]", status.code()),
23 Self::ReadConnection(status) => write!(f, "Connection read error [{}]", status.code()),
24 Self::RequestAborted(status) => write!(f, "Request aborted [{}]", status.code()),
25 Self::TlsStreamConnect(status) => {
26 write!(f, "Tls stream connection error [{}]", status.code())
27 }
28 Self::NeedOpenRedirect(status) => {
29 write!(f, "Open redirect required [{}]", status.code())
30 }
31 Self::MaxRedirectTimes(status) => {
32 write!(f, "Exceeded maximum redirect attempts [{}]", status.code())
33 }
34 Self::MethodsNotSupport(status) => {
35 write!(f, "Http method not supported [{}]", status.code())
36 }
37 Self::RedirectInvalidUrl(status) => {
38 write!(f, "Invalid redirect url [{}]", status.code())
39 }
40 Self::ClientDisconnected(status) => {
41 write!(f, "Client disconnected [{}]", status.code())
42 }
43 Self::RedirectUrlDeadLoop(status) => {
44 write!(f, "Redirect url dead loop detected [{}]", status.code())
45 }
46 Self::ClientClosedConnection(status) => {
47 write!(f, "Client closed connection [{}]", status.code())
48 }
49 Self::IncompleteWebSocketFrame(status) => write!(
50 f,
51 "WebSocket connection closed before a complete frame was received [{}]",
52 status.code()
53 ),
54 Self::RequestTooLong(status) => write!(f, "Request line too long [{}]", status.code()),
55 Self::PathTooLong(status) => write!(f, "Path too long [{}]", status.code()),
56 Self::QueryTooLong(status) => write!(f, "Query string too long [{}]", status.code()),
57 Self::HeaderLineTooLong(status) => {
58 write!(f, "Header line too long [{}]", status.code())
59 }
60 Self::TooManyHeaders(status) => write!(f, "Too many headers [{}]", status.code()),
61 Self::HeaderKeyTooLong(status) => write!(f, "Header key too long [{}]", status.code()),
62 Self::HeaderValueTooLong(status) => {
63 write!(f, "Header value too long [{}]", status.code())
64 }
65 Self::ContentLengthTooLarge(status) => {
66 write!(f, "Content length too large [{}]", status.code())
67 }
68 Self::InvalidContentLength(status) => {
69 write!(f, "Invalid content length [{}]", status.code())
70 }
71 Self::InvalidUrlScheme(status) => write!(f, "Invalid URL scheme [{}]", status.code()),
72 Self::InvalidUrlHost(status) => write!(f, "Invalid URL host [{}]", status.code()),
73 Self::InvalidUrlPort(status) => write!(f, "Invalid URL port [{}]", status.code()),
74 Self::InvalidUrlPath(status) => write!(f, "Invalid URL path [{}]", status.code()),
75 Self::InvalidUrlQuery(status) => write!(f, "Invalid URL query [{}]", status.code()),
76 Self::InvalidUrlFragment(status) => {
77 write!(f, "Invalid URL fragment [{}]", status.code())
78 }
79 Self::ReadTimeoutNotSet(status) => {
80 write!(f, "Failed to set read timeout [{}]", status.code())
81 }
82 Self::WriteTimeoutNotSet(status) => {
83 write!(f, "Failed to set write timeout [{}]", status.code())
84 }
85 Self::TcpConnectionFailed(status) => {
86 write!(f, "Tcp connection failed [{}]", status.code())
87 }
88 Self::TlsHandshakeFailed(status) => {
89 write!(f, "Tls handshake failed [{}]", status.code())
90 }
91 Self::TlsCertificateInvalid(status) => {
92 write!(f, "Tls certificate invalid [{}]", status.code())
93 }
94 Self::WebSocketFrameTooLarge(status) => {
95 write!(f, "WebSocket frame too large [{}]", status.code())
96 }
97 Self::WebSocketOpcodeUnsupported(status) => {
98 write!(f, "WebSocket opcode unsupported [{}]", status.code())
99 }
100 Self::WebSocketMaskMissing(status) => {
101 write!(f, "WebSocket mask missing [{}]", status.code())
102 }
103 Self::WebSocketPayloadCorrupted(status) => {
104 write!(f, "WebSocket payload corrupted [{}]", status.code())
105 }
106 Self::WebSocketInvalidUtf8(status) => {
107 write!(f, "WebSocket invalid UTF-8 [{}]", status.code())
108 }
109 Self::WebSocketInvalidCloseCode(status) => {
110 write!(f, "WebSocket invalid close code [{}]", status.code())
111 }
112 Self::WebSocketInvalidExtension(status) => {
113 write!(f, "WebSocket invalid extension [{}]", status.code())
114 }
115 Self::HttpRequestPartsInsufficient(status) => {
116 write!(f, "HTTP request parts insufficient [{}]", status.code())
117 }
118 Self::TcpStreamConnect(status) => {
119 write!(f, "TCP stream connection error [{}]", status.code())
120 }
121 Self::TlsConnectorBuild(status) => {
122 write!(f, "TLS connector build error [{}]", status.code())
123 }
124 Self::InvalidUrl(status) => {
125 write!(f, "Invalid URL error [{}]", status.code())
126 }
127 Self::SetReadTimeout(status) => {
128 write!(f, "Set read timeout error [{}]", status.code())
129 }
130 Self::SetWriteTimeout(status) => {
131 write!(f, "Set write timeout error [{}]", status.code())
132 }
133 Self::ConfigReadError(status) => {
134 write!(f, "Configuration read error [{}]", status.code())
135 }
136 Self::TcpStreamConnectString(status) => {
137 write!(f, "TCP stream connection error [{}]", status.code())
138 }
139 Self::TlsConnectorBuildString(status) => {
140 write!(f, "TLS connector build error [{}]", status.code())
141 }
142 Self::SetReadTimeoutString(status) => {
143 write!(f, "Set read timeout error [{}]", status.code())
144 }
145 Self::SetWriteTimeoutString(status) => {
146 write!(f, "Set write timeout error [{}]", status.code())
147 }
148 Self::Request(message) => write!(f, "Request error: {message}"),
149 Self::Unknown(status) => write!(f, "Unknown error occurred [{}]", status.code()),
150 }
151 }
152}
153
154impl RequestError {
155 #[inline(always)]
167 pub fn get_http_status(&self) -> HttpStatus {
168 match self {
169 Self::HttpRead(status) => *status,
170 Self::GetTcpStream(status) => *status,
171 Self::GetTlsStream(status) => *status,
172 Self::ReadConnection(status) => *status,
173 Self::RequestAborted(status) => *status,
174 Self::TlsStreamConnect(status) => *status,
175 Self::NeedOpenRedirect(status) => *status,
176 Self::MaxRedirectTimes(status) => *status,
177 Self::MethodsNotSupport(status) => *status,
178 Self::RedirectInvalidUrl(status) => *status,
179 Self::ClientDisconnected(status) => *status,
180 Self::RedirectUrlDeadLoop(status) => *status,
181 Self::ClientClosedConnection(status) => *status,
182 Self::IncompleteWebSocketFrame(status) => *status,
183 Self::RequestTooLong(status) => *status,
184 Self::PathTooLong(status) => *status,
185 Self::QueryTooLong(status) => *status,
186 Self::HeaderLineTooLong(status) => *status,
187 Self::TooManyHeaders(status) => *status,
188 Self::HeaderKeyTooLong(status) => *status,
189 Self::HeaderValueTooLong(status) => *status,
190 Self::ContentLengthTooLarge(status) => *status,
191 Self::InvalidContentLength(status) => *status,
192 Self::InvalidUrlScheme(status) => *status,
193 Self::InvalidUrlHost(status) => *status,
194 Self::InvalidUrlPort(status) => *status,
195 Self::InvalidUrlPath(status) => *status,
196 Self::InvalidUrlQuery(status) => *status,
197 Self::InvalidUrlFragment(status) => *status,
198 Self::ReadTimeoutNotSet(status) => *status,
199 Self::WriteTimeoutNotSet(status) => *status,
200 Self::TcpConnectionFailed(status) => *status,
201 Self::TlsHandshakeFailed(status) => *status,
202 Self::TlsCertificateInvalid(status) => *status,
203 Self::WebSocketFrameTooLarge(status) => *status,
204 Self::WebSocketOpcodeUnsupported(status) => *status,
205 Self::WebSocketMaskMissing(status) => *status,
206 Self::WebSocketPayloadCorrupted(status) => *status,
207 Self::WebSocketInvalidUtf8(status) => *status,
208 Self::WebSocketInvalidCloseCode(status) => *status,
209 Self::WebSocketInvalidExtension(status) => *status,
210 Self::HttpRequestPartsInsufficient(status) => *status,
211 Self::TcpStreamConnect(status) => *status,
212 Self::TlsConnectorBuild(status) => *status,
213 Self::InvalidUrl(status) => *status,
214 Self::SetReadTimeout(status) => *status,
215 Self::SetWriteTimeout(status) => *status,
216 Self::ConfigReadError(status) => *status,
217 Self::TcpStreamConnectString(status) => *status,
218 Self::TlsConnectorBuildString(status) => *status,
219 Self::SetReadTimeoutString(status) => *status,
220 Self::SetWriteTimeoutString(status) => *status,
221 Self::Request(_) => HttpStatus::BadRequest,
222 Self::Unknown(status) => *status,
223 }
224 }
225
226 pub fn get_http_status_code(&self) -> ResponseStatusCode {
238 self.get_http_status().code()
239 }
240}
241
242impl Default for RequestConfig {
243 #[inline(always)]
249 fn default() -> Self {
250 Self {
251 buffer_size: DEFAULT_BUFFER_SIZE,
252 max_request_line_length: DEFAULT_MAX_REQUEST_LINE_LENGTH,
253 max_path_length: DEFAULT_MAX_PATH_LENGTH,
254 max_query_length: DEFAULT_MAX_QUERY_LENGTH,
255 max_header_line_length: DEFAULT_MAX_HEADER_LINE_LENGTH,
256 max_header_count: DEFAULT_MAX_HEADER_COUNT,
257 max_header_key_length: DEFAULT_MAX_HEADER_KEY_LENGTH,
258 max_header_value_length: DEFAULT_MAX_HEADER_VALUE_LENGTH,
259 max_body_size: DEFAULT_MAX_BODY_SIZE,
260 max_ws_frame_size: DEFAULT_MAX_WS_FRAME_SIZE,
261 max_ws_frames: DEFAULT_MAX_WS_FRAMES,
262 http_read_timeout_ms: DEFAULT_HTTP_READ_TIMEOUT_MS,
263 ws_read_timeout_ms: DEFAULT_WS_READ_TIMEOUT_MS,
264 }
265 }
266}
267
268impl RequestConfig {
269 #[inline(always)]
275 pub fn new() -> Self {
276 Self::default()
277 }
278
279 #[inline(always)]
288 pub fn high_security() -> Self {
289 Self {
290 buffer_size: DEFAULT_HIGH_SECURITY_BUFFER_SIZE,
291 max_request_line_length: DEFAULT_HIGH_SECURITY_MAX_REQUEST_LINE_LENGTH,
292 max_path_length: DEFAULT_HIGH_SECURITY_MAX_PATH_LENGTH,
293 max_query_length: DEFAULT_HIGH_SECURITY_MAX_QUERY_LENGTH,
294 max_header_line_length: DEFAULT_HIGH_SECURITY_MAX_HEADER_LINE_LENGTH,
295 max_header_count: DEFAULT_HIGH_SECURITY_MAX_HEADER_COUNT,
296 max_header_key_length: DEFAULT_HIGH_SECURITY_MAX_HEADER_KEY_LENGTH,
297 max_header_value_length: DEFAULT_HIGH_SECURITY_MAX_HEADER_VALUE_LENGTH,
298 max_body_size: DEFAULT_HIGH_SECURITY_MAX_BODY_SIZE,
299 max_ws_frame_size: DEFAULT_HIGH_SECURITY_MAX_WS_FRAME_SIZE,
300 max_ws_frames: DEFAULT_HIGH_SECURITY_MAX_WS_FRAMES,
301 http_read_timeout_ms: DEFAULT_HIGH_SECURITY_HTTP_READ_TIMEOUT_MS,
302 ws_read_timeout_ms: DEFAULT_HIGH_SECURITY_WS_READ_TIMEOUT_MS,
303 }
304 }
305}
306
307impl Default for Request {
311 #[inline(always)]
312 fn default() -> Self {
313 Self {
314 method: Method::default(),
315 host: String::new(),
316 version: HttpVersion::default(),
317 path: String::new(),
318 querys: hash_map_xx_hash3_64(),
319 headers: hash_map_xx_hash3_64(),
320 body: Vec::new(),
321 }
322 }
323}
324
325impl Request {
326 #[inline(always)]
332 pub fn new() -> Self {
333 Self::default()
334 }
335
336 pub async fn http_from_stream(
349 stream: &ArcRwLockStream,
350 config: &RequestConfig,
351 ) -> Result<Request, RequestError> {
352 let mut buf_stream: RwLockWriteGuard<'_, TcpStream> = stream.write().await;
353 let buffer_size: usize = *config.get_buffer_size();
354 let reader: &mut BufReader<&mut TcpStream> =
355 &mut BufReader::with_capacity(buffer_size, &mut buf_stream);
356 let mut request_line: String = String::with_capacity(buffer_size);
357 let timeout_duration: Duration = Duration::from_millis(config.http_read_timeout_ms);
358 let bytes_read: usize = timeout(
359 timeout_duration,
360 AsyncBufReadExt::read_line(reader, &mut request_line),
361 )
362 .await
363 .map_err(|_| RequestError::ReadTimeoutNotSet(HttpStatus::RequestTimeout))?
364 .map_err(|_| RequestError::HttpRead(HttpStatus::BadRequest))?;
365 if bytes_read > config.max_request_line_length {
366 return Err(RequestError::RequestTooLong(HttpStatus::BadRequest));
367 }
368 let parts: Vec<&str> = request_line.split_whitespace().collect();
369 let parts_len: usize = parts.len();
370 if parts_len < 3 {
371 return Err(RequestError::HttpRequestPartsInsufficient(
372 HttpStatus::BadRequest,
373 ));
374 }
375 let full_path: &str = parts[1];
376 if full_path.len() > config.max_path_length {
377 return Err(RequestError::PathTooLong(HttpStatus::URITooLong));
378 }
379 let method: RequestMethod = parts[0]
380 .parse::<RequestMethod>()
381 .unwrap_or(Method::Unknown(parts[0].to_string()));
382 let full_path: RequestPath = full_path.to_string();
383 let version: RequestVersion = parts[2]
384 .parse::<RequestVersion>()
385 .unwrap_or(RequestVersion::Unknown(parts[2].to_string()));
386 let hash_index: Option<usize> = full_path.find(HASH);
387 let query_index: Option<usize> = full_path.find(QUERY);
388 let query_string: String = query_index.map_or_else(String::new, |i| {
389 let temp: &str = &full_path[i + 1..];
390 if hash_index.is_none() || hash_index.unwrap() <= i {
391 return temp.to_owned();
392 }
393 temp.split(HASH).next().unwrap_or_default().to_owned()
394 });
395 if query_string.len() > config.max_query_length {
396 return Err(RequestError::QueryTooLong(HttpStatus::URITooLong));
397 }
398 let querys: RequestQuerys = Self::parse_querys(&query_string);
399 let path: RequestPath = if let Some(i) = query_index.or(hash_index) {
400 full_path[..i].to_owned()
401 } else {
402 full_path.to_owned()
403 };
404 let mut headers: RequestHeaders = hash_map_xx_hash3_64();
405 let mut host: RequestHost = String::new();
406 let mut content_length: usize = 0;
407 let mut header_count: usize = 0;
408 loop {
409 let header_line: &mut String = &mut String::with_capacity(buffer_size);
410 let timeout_duration: Duration = Duration::from_millis(config.http_read_timeout_ms);
411 let bytes_read: usize = timeout(
412 timeout_duration,
413 AsyncBufReadExt::read_line(reader, header_line),
414 )
415 .await
416 .map_err(|_| RequestError::ReadTimeoutNotSet(HttpStatus::RequestTimeout))?
417 .map_err(|_| RequestError::HttpRead(HttpStatus::BadRequest))?;
418 if bytes_read > config.max_header_line_length {
419 return Err(RequestError::HeaderLineTooLong(
420 HttpStatus::RequestHeaderFieldsTooLarge,
421 ));
422 }
423 let header_line: &str = header_line.trim();
424 if header_line.is_empty() {
425 break;
426 }
427 header_count += 1;
428 if header_count > config.max_header_count {
429 return Err(RequestError::TooManyHeaders(
430 HttpStatus::RequestHeaderFieldsTooLarge,
431 ));
432 }
433 if let Some((key_part, value_part)) = header_line.split_once(COLON) {
434 let key: String = key_part.trim().to_ascii_lowercase();
435 if key.is_empty() {
436 continue;
437 }
438 if key.len() > config.max_header_key_length {
439 return Err(RequestError::HeaderKeyTooLong(
440 HttpStatus::RequestHeaderFieldsTooLarge,
441 ));
442 }
443 let value: String = value_part.trim().to_string();
444 if value.len() > config.max_header_value_length {
445 return Err(RequestError::HeaderValueTooLong(
446 HttpStatus::RequestHeaderFieldsTooLarge,
447 ));
448 }
449 if key == HOST {
450 host = value.clone();
451 } else if key == CONTENT_LENGTH {
452 match value.parse::<usize>() {
453 Ok(length) => {
454 if length > config.max_body_size {
455 return Err(RequestError::ContentLengthTooLarge(
456 HttpStatus::PayloadTooLarge,
457 ));
458 }
459 content_length = length;
460 }
461 Err(_) => {
462 return Err(RequestError::InvalidContentLength(HttpStatus::BadRequest));
463 }
464 }
465 }
466 headers.entry(key).or_default().push_back(value);
467 }
468 }
469 let mut body: RequestBody = Vec::with_capacity(content_length);
470 if content_length > 0 {
471 body.resize(content_length, 0);
472 let timeout_duration: Duration = Duration::from_millis(config.http_read_timeout_ms);
473 timeout(
474 timeout_duration,
475 AsyncReadExt::read_exact(reader, &mut body),
476 )
477 .await
478 .map_err(|_| RequestError::ReadTimeoutNotSet(HttpStatus::RequestTimeout))?
479 .map_err(|_| RequestError::ReadConnection(HttpStatus::BadRequest))?;
480 }
481 Ok(Request {
482 method,
483 host,
484 version,
485 path,
486 querys,
487 headers,
488 body,
489 })
490 }
491
492 pub async fn ws_from_stream(
505 &mut self,
506 stream: &ArcRwLockStream,
507 config: &RequestConfig,
508 ) -> Result<Request, RequestError> {
509 let buffer_size: usize = *config.get_buffer_size();
510 let mut dynamic_buffer: Vec<u8> = Vec::with_capacity(buffer_size);
511 let temp_buffer_size: usize = buffer_size;
512 let mut temp_buffer: Vec<u8> = vec![0; temp_buffer_size];
513 let mut full_frame: Vec<u8> = Vec::with_capacity(config.max_ws_frame_size);
514 let mut frame_count: usize = 0;
515 let mut is_client_response: bool = false;
516 let ws_read_timeout_ms: u64 =
517 (config.ws_read_timeout_ms >> 1) + (config.ws_read_timeout_ms & 1);
518 loop {
519 let timeout_duration: Duration = Duration::from_millis(ws_read_timeout_ms);
520 let len: usize = match timeout(
521 timeout_duration,
522 stream.write().await.read(&mut temp_buffer),
523 )
524 .await
525 {
526 Ok(result) => match result {
527 Ok(len) => len,
528 Err(error) => {
529 if error.kind() == ErrorKind::ConnectionReset
530 || error.kind() == ErrorKind::ConnectionAborted
531 {
532 return Err(RequestError::ClientDisconnected(HttpStatus::BadRequest));
533 }
534 return Err(RequestError::Unknown(HttpStatus::InternalServerError));
535 }
536 },
537 Err(_) => {
538 if !is_client_response {
539 return Err(RequestError::ReadTimeoutNotSet(HttpStatus::RequestTimeout));
540 }
541 is_client_response = false;
542 stream.try_send_body(&PING_FRAME).await.map_err(|_| {
543 RequestError::WriteTimeoutNotSet(HttpStatus::InternalServerError)
544 })?;
545 let _ = stream.try_flush().await;
546 continue;
547 }
548 };
549 if len == 0 {
550 return Err(RequestError::IncompleteWebSocketFrame(
551 HttpStatus::BadRequest,
552 ));
553 }
554 dynamic_buffer.extend_from_slice(&temp_buffer[..len]);
555 while let Some((frame, consumed)) = WebSocketFrame::decode_ws_frame(&dynamic_buffer) {
556 is_client_response = true;
557 dynamic_buffer.drain(0..consumed);
558 frame_count += 1;
559 if frame_count > config.max_ws_frames {
560 return Err(RequestError::TooManyHeaders(
561 HttpStatus::RequestHeaderFieldsTooLarge,
562 ));
563 }
564 match frame.get_opcode() {
565 WebSocketOpcode::Close => {
566 return Err(RequestError::ClientClosedConnection(HttpStatus::BadRequest));
567 }
568 WebSocketOpcode::Ping | WebSocketOpcode::Pong => {
569 continue;
570 }
571 WebSocketOpcode::Text | WebSocketOpcode::Binary => {
572 let payload_data: &[u8] = frame.get_payload_data();
573 if payload_data.len() > config.max_ws_frame_size {
574 return Err(RequestError::WebSocketFrameTooLarge(
575 HttpStatus::PayloadTooLarge,
576 ));
577 }
578 if full_frame.len() + payload_data.len() > config.max_ws_frame_size {
579 return Err(RequestError::WebSocketFrameTooLarge(
580 HttpStatus::PayloadTooLarge,
581 ));
582 }
583 full_frame.extend_from_slice(payload_data);
584 if *frame.get_fin() {
585 let mut request: Request = self.clone();
586 request.body = full_frame;
587 return Ok(request);
588 }
589 }
590 _ => {
591 return Err(RequestError::WebSocketOpcodeUnsupported(
592 HttpStatus::NotImplemented,
593 ));
594 }
595 }
596 }
597 }
598 }
599
600 fn parse_querys<Q>(query: Q) -> RequestQuerys
612 where
613 Q: AsRef<str>,
614 {
615 let mut query_map: RequestQuerys = hash_map_xx_hash3_64();
616 for pair in query.as_ref().split(AND) {
617 if let Some((key, value)) = pair.split_once(EQUAL) {
618 if !key.is_empty() {
619 query_map.insert(key.to_string(), value.to_string());
620 }
621 } else if !pair.is_empty() {
622 query_map.insert(pair.to_string(), String::new());
623 }
624 }
625 query_map
626 }
627
628 #[inline(always)]
640 pub fn try_get_query<K>(&self, key: K) -> Option<RequestQuerysValue>
641 where
642 K: AsRef<str>,
643 {
644 self.querys.get(key.as_ref()).cloned()
645 }
646
647 #[inline(always)]
663 pub fn get_query<K>(&self, key: K) -> RequestQuerysValue
664 where
665 K: AsRef<str>,
666 {
667 self.try_get_query(key).unwrap()
668 }
669
670 #[inline(always)]
680 pub fn try_get_header<K>(&self, key: K) -> Option<RequestHeadersValue>
681 where
682 K: AsRef<str>,
683 {
684 self.headers.get(key.as_ref()).cloned()
685 }
686
687 #[inline(always)]
701 pub fn get_header<K>(&self, key: K) -> RequestHeadersValue
702 where
703 K: AsRef<str>,
704 {
705 self.try_get_header(key).unwrap()
706 }
707
708 #[inline(always)]
718 pub fn try_get_header_front<K>(&self, key: K) -> Option<RequestHeadersValueItem>
719 where
720 K: AsRef<str>,
721 {
722 self.headers
723 .get(key.as_ref())
724 .and_then(|values| values.front().cloned())
725 }
726
727 #[inline(always)]
741 pub fn get_header_front<K>(&self, key: K) -> RequestHeadersValueItem
742 where
743 K: AsRef<str>,
744 {
745 self.try_get_header_front(key).unwrap()
746 }
747
748 #[inline(always)]
758 pub fn try_get_header_back<K>(&self, key: K) -> Option<RequestHeadersValueItem>
759 where
760 K: AsRef<str>,
761 {
762 self.headers
763 .get(key.as_ref())
764 .and_then(|values| values.back().cloned())
765 }
766
767 #[inline(always)]
781 pub fn get_header_back<K>(&self, key: K) -> RequestHeadersValueItem
782 where
783 K: AsRef<str>,
784 {
785 self.try_get_header_back(key).unwrap()
786 }
787
788 #[inline(always)]
798 pub fn try_get_header_length<K>(&self, key: K) -> Option<usize>
799 where
800 K: AsRef<str>,
801 {
802 self.headers.get(key.as_ref()).map(|values| values.len())
803 }
804
805 #[inline(always)]
819 pub fn get_header_length<K>(&self, key: K) -> usize
820 where
821 K: AsRef<str>,
822 {
823 self.try_get_header_length(key).unwrap()
824 }
825
826 #[inline(always)]
832 pub fn get_headers_values_length(&self) -> usize {
833 self.headers.values().map(|values| values.len()).sum()
834 }
835
836 #[inline(always)]
842 pub fn get_headers_length(&self) -> usize {
843 self.headers.len()
844 }
845
846 #[inline(always)]
856 pub fn has_header<K>(&self, key: K) -> bool
857 where
858 K: AsRef<str>,
859 {
860 self.headers.contains_key(key.as_ref())
861 }
862
863 #[inline(always)]
874 pub fn has_header_value<K, V>(&self, key: K, value: V) -> bool
875 where
876 K: AsRef<str>,
877 V: AsRef<str>,
878 {
879 if let Some(values) = self.headers.get(key.as_ref()) {
880 values.contains(&value.as_ref().to_owned())
881 } else {
882 false
883 }
884 }
885
886 #[inline(always)]
895 pub fn get_body_string(&self) -> String {
896 String::from_utf8_lossy(self.get_body()).into_owned()
897 }
898
899 pub fn try_get_body_json<T>(&self) -> Result<T, serde_json::Error>
912 where
913 T: DeserializeOwned,
914 {
915 serde_json::from_slice(self.get_body())
916 }
917
918 pub fn get_body_json<T>(&self) -> T
935 where
936 T: DeserializeOwned,
937 {
938 self.try_get_body_json().unwrap()
939 }
940
941 #[inline(always)]
950 pub fn get_string(&self) -> String {
951 let body: &Vec<u8> = self.get_body();
952 let body_type: &'static str = if std::str::from_utf8(body).is_ok() {
953 PLAIN
954 } else {
955 BINARY
956 };
957 format!(
958 "[Request] => [method]: {}; [host]: {}; [version]: {}; [path]: {}; [querys]: {:?}; [headers]: {:?}; [body]: {} bytes {};",
959 self.get_method(),
960 self.get_host(),
961 self.get_version(),
962 self.get_path(),
963 self.get_querys(),
964 self.get_headers(),
965 body.len(),
966 body_type
967 )
968 }
969
970 #[inline(always)]
980 pub fn get_upgrade_type(&self) -> UpgradeType {
981 let upgrade_type: UpgradeType = self
982 .try_get_header_back(UPGRADE)
983 .and_then(|data| data.parse::<UpgradeType>().ok())
984 .unwrap_or_default();
985 upgrade_type
986 }
987
988 #[inline(always)]
996 pub fn is_ws(&self) -> bool {
997 self.get_upgrade_type().is_ws()
998 }
999
1000 #[inline(always)]
1006 pub fn is_h2c(&self) -> bool {
1007 self.get_upgrade_type().is_h2c()
1008 }
1009
1010 #[inline(always)]
1016 pub fn is_tls(&self) -> bool {
1017 self.get_upgrade_type().is_tls()
1018 }
1019
1020 #[inline(always)]
1026 pub fn is_unknown_upgrade(&self) -> bool {
1027 self.get_upgrade_type().is_unknown()
1028 }
1029
1030 #[inline(always)]
1036 pub fn is_http1_1_or_higher(&self) -> bool {
1037 self.get_version().is_http1_1_or_higher()
1038 }
1039
1040 #[inline(always)]
1046 pub fn is_http0_9(&self) -> bool {
1047 self.get_version().is_http0_9()
1048 }
1049
1050 #[inline(always)]
1056 pub fn is_http1_0(&self) -> bool {
1057 self.get_version().is_http1_0()
1058 }
1059
1060 #[inline(always)]
1066 pub fn is_http1_1(&self) -> bool {
1067 self.get_version().is_http1_1()
1068 }
1069
1070 #[inline(always)]
1076 pub fn is_http2(&self) -> bool {
1077 self.get_version().is_http2()
1078 }
1079
1080 #[inline(always)]
1086 pub fn is_http3(&self) -> bool {
1087 self.get_version().is_http3()
1088 }
1089
1090 #[inline(always)]
1096 pub fn is_unknown_version(&self) -> bool {
1097 self.get_version().is_unknown()
1098 }
1099
1100 #[inline(always)]
1106 pub fn is_http(&self) -> bool {
1107 self.get_version().is_http()
1108 }
1109
1110 #[inline(always)]
1116 pub fn is_get(&self) -> bool {
1117 self.get_method().is_get()
1118 }
1119
1120 #[inline(always)]
1126 pub fn is_post(&self) -> bool {
1127 self.get_method().is_post()
1128 }
1129
1130 #[inline(always)]
1136 pub fn is_put(&self) -> bool {
1137 self.get_method().is_put()
1138 }
1139
1140 #[inline(always)]
1146 pub fn is_delete(&self) -> bool {
1147 self.get_method().is_delete()
1148 }
1149
1150 #[inline(always)]
1156 pub fn is_patch(&self) -> bool {
1157 self.get_method().is_patch()
1158 }
1159
1160 #[inline(always)]
1166 pub fn is_head(&self) -> bool {
1167 self.get_method().is_head()
1168 }
1169
1170 #[inline(always)]
1176 pub fn is_options(&self) -> bool {
1177 self.get_method().is_options()
1178 }
1179
1180 #[inline(always)]
1186 pub fn is_connect(&self) -> bool {
1187 self.get_method().is_connect()
1188 }
1189
1190 #[inline(always)]
1196 pub fn is_trace(&self) -> bool {
1197 self.get_method().is_trace()
1198 }
1199
1200 #[inline(always)]
1206 pub fn is_unknown_method(&self) -> bool {
1207 self.get_method().is_unknown()
1208 }
1209
1210 #[inline(always)]
1226 pub fn is_enable_keep_alive(&self) -> bool {
1227 if let Some(connection_value) = self.try_get_header_back(CONNECTION) {
1228 if connection_value.eq_ignore_ascii_case(KEEP_ALIVE) {
1229 return true;
1230 } else if connection_value.eq_ignore_ascii_case(CLOSE) {
1231 return self.is_ws();
1232 }
1233 }
1234 self.is_http1_1_or_higher() || self.is_ws()
1235 }
1236
1237 #[inline(always)]
1243 pub fn is_disable_keep_alive(&self) -> bool {
1244 !self.is_enable_keep_alive()
1245 }
1246}