1use crate::*;
2
3impl std::error::Error for RequestError {}
5
6impl Display for RequestError {
8 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9 match self {
10 Self::HttpRead(status) => write!(f, "Http read error [{}]", status.code()),
11 Self::GetTcpStream(status) => write!(f, "Failed to get tcp stream [{}]", status.code()),
12 Self::GetTlsStream(status) => write!(f, "Failed to get tls stream [{}]", status.code()),
13 Self::ReadConnection(status) => write!(f, "Connection read error [{}]", status.code()),
14 Self::RequestAborted(status) => write!(f, "Request aborted [{}]", status.code()),
15 Self::TlsStreamConnect(status) => {
16 write!(f, "Tls stream connection error [{}]", status.code())
17 }
18 Self::NeedOpenRedirect(status) => {
19 write!(f, "Open redirect required [{}]", status.code())
20 }
21 Self::MaxRedirectTimes(status) => {
22 write!(f, "Exceeded maximum redirect attempts [{}]", status.code())
23 }
24 Self::MethodsNotSupport(status) => {
25 write!(f, "Http method not supported [{}]", status.code())
26 }
27 Self::RedirectInvalidUrl(status) => {
28 write!(f, "Invalid redirect url [{}]", status.code())
29 }
30 Self::ClientDisconnected(status) => {
31 write!(f, "Client disconnected [{}]", status.code())
32 }
33 Self::RedirectUrlDeadLoop(status) => {
34 write!(f, "Redirect url dead loop detected [{}]", status.code())
35 }
36 Self::ClientClosedConnection(status) => {
37 write!(f, "Client closed connection [{}]", status.code())
38 }
39 Self::IncompleteWebSocketFrame(status) => write!(
40 f,
41 "WebSocket connection closed before a complete frame was received [{}]",
42 status.code()
43 ),
44 Self::RequestTooLong(status) => write!(f, "Request line too long [{}]", status.code()),
45 Self::PathTooLong(status) => write!(f, "Path too long [{}]", status.code()),
46 Self::QueryTooLong(status) => write!(f, "Query string too long [{}]", status.code()),
47 Self::HeaderLineTooLong(status) => {
48 write!(f, "Header line too long [{}]", status.code())
49 }
50 Self::TooManyHeaders(status) => write!(f, "Too many headers [{}]", status.code()),
51 Self::HeaderKeyTooLong(status) => write!(f, "Header key too long [{}]", status.code()),
52 Self::HeaderValueTooLong(status) => {
53 write!(f, "Header value too long [{}]", status.code())
54 }
55 Self::ContentLengthTooLarge(status) => {
56 write!(f, "Content length too large [{}]", status.code())
57 }
58 Self::InvalidContentLength(status) => {
59 write!(f, "Invalid content length [{}]", status.code())
60 }
61 Self::InvalidUrlScheme(status) => write!(f, "Invalid URL scheme [{}]", status.code()),
62 Self::InvalidUrlHost(status) => write!(f, "Invalid URL host [{}]", status.code()),
63 Self::InvalidUrlPort(status) => write!(f, "Invalid URL port [{}]", status.code()),
64 Self::InvalidUrlPath(status) => write!(f, "Invalid URL path [{}]", status.code()),
65 Self::InvalidUrlQuery(status) => write!(f, "Invalid URL query [{}]", status.code()),
66 Self::InvalidUrlFragment(status) => {
67 write!(f, "Invalid URL fragment [{}]", status.code())
68 }
69 Self::ReadTimeoutNotSet(status) => {
70 write!(f, "Failed to set read timeout [{}]", status.code())
71 }
72 Self::WriteTimeoutNotSet(status) => {
73 write!(f, "Failed to set write timeout [{}]", status.code())
74 }
75 Self::TcpConnectionFailed(status) => {
76 write!(f, "Tcp connection failed [{}]", status.code())
77 }
78 Self::TlsHandshakeFailed(status) => {
79 write!(f, "Tls handshake failed [{}]", status.code())
80 }
81 Self::TlsCertificateInvalid(status) => {
82 write!(f, "Tls certificate invalid [{}]", status.code())
83 }
84 Self::WebSocketFrameTooLarge(status) => {
85 write!(f, "WebSocket frame too large [{}]", status.code())
86 }
87 Self::WebSocketOpcodeUnsupported(status) => {
88 write!(f, "WebSocket opcode unsupported [{}]", status.code())
89 }
90 Self::WebSocketMaskMissing(status) => {
91 write!(f, "WebSocket mask missing [{}]", status.code())
92 }
93 Self::WebSocketPayloadCorrupted(status) => {
94 write!(f, "WebSocket payload corrupted [{}]", status.code())
95 }
96 Self::WebSocketInvalidUtf8(status) => {
97 write!(f, "WebSocket invalid UTF-8 [{}]", status.code())
98 }
99 Self::WebSocketInvalidCloseCode(status) => {
100 write!(f, "WebSocket invalid close code [{}]", status.code())
101 }
102 Self::WebSocketInvalidExtension(status) => {
103 write!(f, "WebSocket invalid extension [{}]", status.code())
104 }
105 Self::HttpRequestPartsInsufficient(status) => {
106 write!(f, "HTTP request parts insufficient [{}]", status.code())
107 }
108 Self::TcpStreamConnect(status) => {
109 write!(f, "TCP stream connection error [{}]", status.code())
110 }
111 Self::TlsConnectorBuild(status) => {
112 write!(f, "TLS connector build error [{}]", status.code())
113 }
114 Self::InvalidUrl(status) => {
115 write!(f, "Invalid URL error [{}]", status.code())
116 }
117 Self::SetReadTimeout(status) => {
118 write!(f, "Set read timeout error [{}]", status.code())
119 }
120 Self::SetWriteTimeout(status) => {
121 write!(f, "Set write timeout error [{}]", status.code())
122 }
123 Self::ConfigReadError(status) => {
124 write!(f, "Configuration read error [{}]", status.code())
125 }
126 Self::TcpStreamConnectString(status) => {
127 write!(f, "TCP stream connection error [{}]", status.code())
128 }
129 Self::TlsConnectorBuildString(status) => {
130 write!(f, "TLS connector build error [{}]", status.code())
131 }
132 Self::SetReadTimeoutString(status) => {
133 write!(f, "Set read timeout error [{}]", status.code())
134 }
135 Self::SetWriteTimeoutString(status) => {
136 write!(f, "Set write timeout error [{}]", status.code())
137 }
138 Self::Request(message) => write!(f, "Request error: {message}"),
139 Self::Unknown(status) => write!(f, "Unknown error occurred [{}]", status.code()),
140 }
141 }
142}
143
144impl RequestError {
145 #[inline(always)]
157 pub fn get_http_status(&self) -> HttpStatus {
158 match self {
159 Self::HttpRead(status) => *status,
160 Self::GetTcpStream(status) => *status,
161 Self::GetTlsStream(status) => *status,
162 Self::ReadConnection(status) => *status,
163 Self::RequestAborted(status) => *status,
164 Self::TlsStreamConnect(status) => *status,
165 Self::NeedOpenRedirect(status) => *status,
166 Self::MaxRedirectTimes(status) => *status,
167 Self::MethodsNotSupport(status) => *status,
168 Self::RedirectInvalidUrl(status) => *status,
169 Self::ClientDisconnected(status) => *status,
170 Self::RedirectUrlDeadLoop(status) => *status,
171 Self::ClientClosedConnection(status) => *status,
172 Self::IncompleteWebSocketFrame(status) => *status,
173 Self::RequestTooLong(status) => *status,
174 Self::PathTooLong(status) => *status,
175 Self::QueryTooLong(status) => *status,
176 Self::HeaderLineTooLong(status) => *status,
177 Self::TooManyHeaders(status) => *status,
178 Self::HeaderKeyTooLong(status) => *status,
179 Self::HeaderValueTooLong(status) => *status,
180 Self::ContentLengthTooLarge(status) => *status,
181 Self::InvalidContentLength(status) => *status,
182 Self::InvalidUrlScheme(status) => *status,
183 Self::InvalidUrlHost(status) => *status,
184 Self::InvalidUrlPort(status) => *status,
185 Self::InvalidUrlPath(status) => *status,
186 Self::InvalidUrlQuery(status) => *status,
187 Self::InvalidUrlFragment(status) => *status,
188 Self::ReadTimeoutNotSet(status) => *status,
189 Self::WriteTimeoutNotSet(status) => *status,
190 Self::TcpConnectionFailed(status) => *status,
191 Self::TlsHandshakeFailed(status) => *status,
192 Self::TlsCertificateInvalid(status) => *status,
193 Self::WebSocketFrameTooLarge(status) => *status,
194 Self::WebSocketOpcodeUnsupported(status) => *status,
195 Self::WebSocketMaskMissing(status) => *status,
196 Self::WebSocketPayloadCorrupted(status) => *status,
197 Self::WebSocketInvalidUtf8(status) => *status,
198 Self::WebSocketInvalidCloseCode(status) => *status,
199 Self::WebSocketInvalidExtension(status) => *status,
200 Self::HttpRequestPartsInsufficient(status) => *status,
201 Self::TcpStreamConnect(status) => *status,
202 Self::TlsConnectorBuild(status) => *status,
203 Self::InvalidUrl(status) => *status,
204 Self::SetReadTimeout(status) => *status,
205 Self::SetWriteTimeout(status) => *status,
206 Self::ConfigReadError(status) => *status,
207 Self::TcpStreamConnectString(status) => *status,
208 Self::TlsConnectorBuildString(status) => *status,
209 Self::SetReadTimeoutString(status) => *status,
210 Self::SetWriteTimeoutString(status) => *status,
211 Self::Request(_) => HttpStatus::BadRequest,
212 Self::Unknown(status) => *status,
213 }
214 }
215
216 pub fn get_http_status_code(&self) -> ResponseStatusCode {
228 self.get_http_status().code()
229 }
230}
231
232impl Default for RequestConfig {
233 #[inline(always)]
239 fn default() -> Self {
240 Self {
241 buffer_size: DEFAULT_BUFFER_SIZE,
242 max_request_line_length: DEFAULT_MAX_REQUEST_LINE_LENGTH,
243 max_path_length: DEFAULT_MAX_PATH_LENGTH,
244 max_query_length: DEFAULT_MAX_QUERY_LENGTH,
245 max_header_line_length: DEFAULT_MAX_HEADER_LINE_LENGTH,
246 max_header_count: DEFAULT_MAX_HEADER_COUNT,
247 max_header_key_length: DEFAULT_MAX_HEADER_KEY_LENGTH,
248 max_header_value_length: DEFAULT_MAX_HEADER_VALUE_LENGTH,
249 max_body_size: DEFAULT_MAX_BODY_SIZE,
250 max_ws_frame_size: DEFAULT_MAX_WS_FRAME_SIZE,
251 max_ws_frames: DEFAULT_MAX_WS_FRAMES,
252 http_read_timeout_ms: DEFAULT_HTTP_READ_TIMEOUT_MS,
253 ws_read_timeout_ms: DEFAULT_WS_READ_TIMEOUT_MS,
254 }
255 }
256}
257
258impl RequestConfig {
259 #[inline(always)]
265 pub fn new() -> Self {
266 Self::default()
267 }
268
269 #[inline(always)]
278 pub fn high_security() -> Self {
279 Self {
280 buffer_size: DEFAULT_HIGH_SECURITY_BUFFER_SIZE,
281 max_request_line_length: DEFAULT_HIGH_SECURITY_MAX_REQUEST_LINE_LENGTH,
282 max_path_length: DEFAULT_HIGH_SECURITY_MAX_PATH_LENGTH,
283 max_query_length: DEFAULT_HIGH_SECURITY_MAX_QUERY_LENGTH,
284 max_header_line_length: DEFAULT_HIGH_SECURITY_MAX_HEADER_LINE_LENGTH,
285 max_header_count: DEFAULT_HIGH_SECURITY_MAX_HEADER_COUNT,
286 max_header_key_length: DEFAULT_HIGH_SECURITY_MAX_HEADER_KEY_LENGTH,
287 max_header_value_length: DEFAULT_HIGH_SECURITY_MAX_HEADER_VALUE_LENGTH,
288 max_body_size: DEFAULT_HIGH_SECURITY_MAX_BODY_SIZE,
289 max_ws_frame_size: DEFAULT_HIGH_SECURITY_MAX_WS_FRAME_SIZE,
290 max_ws_frames: DEFAULT_HIGH_SECURITY_MAX_WS_FRAMES,
291 http_read_timeout_ms: DEFAULT_HIGH_SECURITY_HTTP_READ_TIMEOUT_MS,
292 ws_read_timeout_ms: DEFAULT_HIGH_SECURITY_WS_READ_TIMEOUT_MS,
293 }
294 }
295}
296
297impl Default for Request {
301 #[inline(always)]
302 fn default() -> Self {
303 Self {
304 method: Method::default(),
305 host: String::new(),
306 version: HttpVersion::default(),
307 path: String::new(),
308 querys: hash_map_xx_hash3_64(),
309 headers: hash_map_xx_hash3_64(),
310 body: Vec::new(),
311 }
312 }
313}
314
315impl Request {
316 #[inline(always)]
322 pub fn new() -> Self {
323 Self::default()
324 }
325
326 pub async fn http_from_stream(
339 stream: &ArcRwLockStream,
340 config: &RequestConfig,
341 ) -> Result<Request, RequestError> {
342 let mut buf_stream: RwLockWriteGuard<'_, TcpStream> = stream.write().await;
343 let buffer_size: usize = *config.get_buffer_size();
344 let reader: &mut BufReader<&mut TcpStream> =
345 &mut BufReader::with_capacity(buffer_size, &mut buf_stream);
346 let mut request_line: String = String::with_capacity(buffer_size);
347 let timeout_duration: Duration = Duration::from_millis(config.http_read_timeout_ms);
348 let bytes_read: usize = timeout(
349 timeout_duration,
350 AsyncBufReadExt::read_line(reader, &mut request_line),
351 )
352 .await
353 .map_err(|_| RequestError::ReadTimeoutNotSet(HttpStatus::RequestTimeout))?
354 .map_err(|_| RequestError::HttpRead(HttpStatus::BadRequest))?;
355 if bytes_read > config.max_request_line_length {
356 return Err(RequestError::RequestTooLong(HttpStatus::BadRequest));
357 }
358 let parts: Vec<&str> = request_line.split_whitespace().collect();
359 let parts_len: usize = parts.len();
360 if parts_len < 3 {
361 return Err(RequestError::HttpRequestPartsInsufficient(
362 HttpStatus::BadRequest,
363 ));
364 }
365 let full_path: &str = parts[1];
366 if full_path.len() > config.max_path_length {
367 return Err(RequestError::PathTooLong(HttpStatus::URITooLong));
368 }
369 let method: RequestMethod = parts[0]
370 .parse::<RequestMethod>()
371 .unwrap_or(Method::Unknown(parts[0].to_string()));
372 let full_path: RequestPath = full_path.to_string();
373 let version: RequestVersion = parts[2]
374 .parse::<RequestVersion>()
375 .unwrap_or(RequestVersion::Unknown(parts[2].to_string()));
376 let hash_index: Option<usize> = full_path.find(HASH);
377 let query_index: Option<usize> = full_path.find(QUERY);
378 let query_string: String = query_index.map_or_else(String::new, |i| {
379 let temp: &str = &full_path[i + 1..];
380 if hash_index.is_none() || hash_index.unwrap() <= i {
381 return temp.to_owned();
382 }
383 temp.split(HASH).next().unwrap_or_default().to_owned()
384 });
385 if query_string.len() > config.max_query_length {
386 return Err(RequestError::QueryTooLong(HttpStatus::URITooLong));
387 }
388 let querys: RequestQuerys = Self::parse_querys(&query_string);
389 let path: RequestPath = if let Some(i) = query_index.or(hash_index) {
390 full_path[..i].to_owned()
391 } else {
392 full_path.to_owned()
393 };
394 let mut headers: RequestHeaders = hash_map_xx_hash3_64();
395 let mut host: RequestHost = String::new();
396 let mut content_length: usize = 0;
397 let mut header_count: usize = 0;
398 loop {
399 let header_line: &mut String = &mut String::with_capacity(buffer_size);
400 let timeout_duration: Duration = Duration::from_millis(config.http_read_timeout_ms);
401 let bytes_read: usize = timeout(
402 timeout_duration,
403 AsyncBufReadExt::read_line(reader, header_line),
404 )
405 .await
406 .map_err(|_| RequestError::ReadTimeoutNotSet(HttpStatus::RequestTimeout))?
407 .map_err(|_| RequestError::HttpRead(HttpStatus::BadRequest))?;
408 if bytes_read > config.max_header_line_length {
409 return Err(RequestError::HeaderLineTooLong(
410 HttpStatus::RequestHeaderFieldsTooLarge,
411 ));
412 }
413 let header_line: &str = header_line.trim();
414 if header_line.is_empty() {
415 break;
416 }
417 header_count += 1;
418 if header_count > config.max_header_count {
419 return Err(RequestError::TooManyHeaders(
420 HttpStatus::RequestHeaderFieldsTooLarge,
421 ));
422 }
423 if let Some((key_part, value_part)) = header_line.split_once(COLON) {
424 let key: String = key_part.trim().to_ascii_lowercase();
425 if key.is_empty() {
426 continue;
427 }
428 if key.len() > config.max_header_key_length {
429 return Err(RequestError::HeaderKeyTooLong(
430 HttpStatus::RequestHeaderFieldsTooLarge,
431 ));
432 }
433 let value: String = value_part.trim().to_string();
434 if value.len() > config.max_header_value_length {
435 return Err(RequestError::HeaderValueTooLong(
436 HttpStatus::RequestHeaderFieldsTooLarge,
437 ));
438 }
439 if key == HOST {
440 host = value.clone();
441 } else if key == CONTENT_LENGTH {
442 match value.parse::<usize>() {
443 Ok(length) => {
444 if length > config.max_body_size {
445 return Err(RequestError::ContentLengthTooLarge(
446 HttpStatus::PayloadTooLarge,
447 ));
448 }
449 content_length = length;
450 }
451 Err(_) => {
452 return Err(RequestError::InvalidContentLength(HttpStatus::BadRequest));
453 }
454 }
455 }
456 headers.entry(key).or_default().push_back(value);
457 }
458 }
459 let mut body: RequestBody = Vec::with_capacity(content_length);
460 if content_length > 0 {
461 body.resize(content_length, 0);
462 let timeout_duration: Duration = Duration::from_millis(config.http_read_timeout_ms);
463 timeout(
464 timeout_duration,
465 AsyncReadExt::read_exact(reader, &mut body),
466 )
467 .await
468 .map_err(|_| RequestError::ReadTimeoutNotSet(HttpStatus::RequestTimeout))?
469 .map_err(|_| RequestError::ReadConnection(HttpStatus::BadRequest))?;
470 }
471 Ok(Request {
472 method,
473 host,
474 version,
475 path,
476 querys,
477 headers,
478 body,
479 })
480 }
481
482 pub async fn ws_from_stream(
495 &mut self,
496 stream: &ArcRwLockStream,
497 config: &RequestConfig,
498 ) -> Result<Request, RequestError> {
499 let buffer_size: usize = *config.get_buffer_size();
500 let mut dynamic_buffer: Vec<u8> = Vec::with_capacity(buffer_size);
501 let temp_buffer_size: usize = buffer_size;
502 let mut temp_buffer: Vec<u8> = vec![0; temp_buffer_size];
503 let mut full_frame: Vec<u8> = Vec::with_capacity(config.max_ws_frame_size);
504 let mut frame_count: usize = 0;
505 let mut is_client_response: bool = false;
506 let ws_read_timeout_ms: u64 =
507 (config.ws_read_timeout_ms >> 1) + (config.ws_read_timeout_ms & 1);
508 loop {
509 let timeout_duration: Duration = Duration::from_millis(ws_read_timeout_ms);
510 let len: usize = match timeout(
511 timeout_duration,
512 stream.write().await.read(&mut temp_buffer),
513 )
514 .await
515 {
516 Ok(result) => match result {
517 Ok(len) => len,
518 Err(error) => {
519 if error.kind() == ErrorKind::ConnectionReset
520 || error.kind() == ErrorKind::ConnectionAborted
521 {
522 return Err(RequestError::ClientDisconnected(HttpStatus::BadRequest));
523 }
524 return Err(RequestError::Unknown(HttpStatus::InternalServerError));
525 }
526 },
527 Err(_) => {
528 if !is_client_response {
529 return Err(RequestError::ReadTimeoutNotSet(HttpStatus::RequestTimeout));
530 }
531 is_client_response = false;
532 stream.try_send_body(&PING_FRAME).await.map_err(|_| {
533 RequestError::WriteTimeoutNotSet(HttpStatus::InternalServerError)
534 })?;
535 let _ = stream.try_flush().await;
536 continue;
537 }
538 };
539 if len == 0 {
540 return Err(RequestError::IncompleteWebSocketFrame(
541 HttpStatus::BadRequest,
542 ));
543 }
544 dynamic_buffer.extend_from_slice(&temp_buffer[..len]);
545 while let Some((frame, consumed)) = WebSocketFrame::decode_ws_frame(&dynamic_buffer) {
546 is_client_response = true;
547 dynamic_buffer.drain(0..consumed);
548 frame_count += 1;
549 if frame_count > config.max_ws_frames {
550 return Err(RequestError::TooManyHeaders(
551 HttpStatus::RequestHeaderFieldsTooLarge,
552 ));
553 }
554 match frame.get_opcode() {
555 WebSocketOpcode::Close => {
556 return Err(RequestError::ClientClosedConnection(HttpStatus::BadRequest));
557 }
558 WebSocketOpcode::Ping | WebSocketOpcode::Pong => {
559 continue;
560 }
561 WebSocketOpcode::Text | WebSocketOpcode::Binary => {
562 let payload_data: &[u8] = frame.get_payload_data();
563 if payload_data.len() > config.max_ws_frame_size {
564 return Err(RequestError::WebSocketFrameTooLarge(
565 HttpStatus::PayloadTooLarge,
566 ));
567 }
568 if full_frame.len() + payload_data.len() > config.max_ws_frame_size {
569 return Err(RequestError::WebSocketFrameTooLarge(
570 HttpStatus::PayloadTooLarge,
571 ));
572 }
573 full_frame.extend_from_slice(payload_data);
574 if *frame.get_fin() {
575 let mut request: Request = self.clone();
576 request.body = full_frame;
577 return Ok(request);
578 }
579 }
580 _ => {
581 return Err(RequestError::WebSocketOpcodeUnsupported(
582 HttpStatus::NotImplemented,
583 ));
584 }
585 }
586 }
587 }
588 }
589
590 fn parse_querys<Q>(query: Q) -> RequestQuerys
602 where
603 Q: AsRef<str>,
604 {
605 let mut query_map: RequestQuerys = hash_map_xx_hash3_64();
606 for pair in query.as_ref().split(AND) {
607 if let Some((key, value)) = pair.split_once(EQUAL) {
608 if !key.is_empty() {
609 query_map.insert(key.to_string(), value.to_string());
610 }
611 } else if !pair.is_empty() {
612 query_map.insert(pair.to_string(), String::new());
613 }
614 }
615 query_map
616 }
617
618 #[inline(always)]
630 pub fn try_get_query<K>(&self, key: K) -> Option<RequestQuerysValue>
631 where
632 K: AsRef<str>,
633 {
634 self.querys.get(key.as_ref()).cloned()
635 }
636
637 #[inline(always)]
653 pub fn get_query<K>(&self, key: K) -> RequestQuerysValue
654 where
655 K: AsRef<str>,
656 {
657 self.try_get_query(key).unwrap()
658 }
659
660 #[inline(always)]
670 pub fn try_get_header<K>(&self, key: K) -> Option<RequestHeadersValue>
671 where
672 K: AsRef<str>,
673 {
674 self.headers.get(key.as_ref()).cloned()
675 }
676
677 #[inline(always)]
691 pub fn get_header<K>(&self, key: K) -> RequestHeadersValue
692 where
693 K: AsRef<str>,
694 {
695 self.try_get_header(key).unwrap()
696 }
697
698 #[inline(always)]
708 pub fn try_get_header_front<K>(&self, key: K) -> Option<RequestHeadersValueItem>
709 where
710 K: AsRef<str>,
711 {
712 self.headers
713 .get(key.as_ref())
714 .and_then(|values| values.front().cloned())
715 }
716
717 #[inline(always)]
731 pub fn get_header_front<K>(&self, key: K) -> RequestHeadersValueItem
732 where
733 K: AsRef<str>,
734 {
735 self.try_get_header_front(key).unwrap()
736 }
737
738 #[inline(always)]
748 pub fn try_get_header_back<K>(&self, key: K) -> Option<RequestHeadersValueItem>
749 where
750 K: AsRef<str>,
751 {
752 self.headers
753 .get(key.as_ref())
754 .and_then(|values| values.back().cloned())
755 }
756
757 #[inline(always)]
771 pub fn get_header_back<K>(&self, key: K) -> RequestHeadersValueItem
772 where
773 K: AsRef<str>,
774 {
775 self.try_get_header_back(key).unwrap()
776 }
777
778 #[inline(always)]
788 pub fn try_get_header_length<K>(&self, key: K) -> Option<usize>
789 where
790 K: AsRef<str>,
791 {
792 self.headers.get(key.as_ref()).map(|values| values.len())
793 }
794
795 #[inline(always)]
809 pub fn get_header_length<K>(&self, key: K) -> usize
810 where
811 K: AsRef<str>,
812 {
813 self.try_get_header_length(key).unwrap()
814 }
815
816 #[inline(always)]
822 pub fn get_headers_values_length(&self) -> usize {
823 self.headers.values().map(|values| values.len()).sum()
824 }
825
826 #[inline(always)]
832 pub fn get_headers_length(&self) -> usize {
833 self.headers.len()
834 }
835
836 #[inline(always)]
846 pub fn has_header<K>(&self, key: K) -> bool
847 where
848 K: AsRef<str>,
849 {
850 self.headers.contains_key(key.as_ref())
851 }
852
853 #[inline(always)]
864 pub fn has_header_value<K, V>(&self, key: K, value: V) -> bool
865 where
866 K: AsRef<str>,
867 V: AsRef<str>,
868 {
869 if let Some(values) = self.headers.get(key.as_ref()) {
870 values.contains(&value.as_ref().to_owned())
871 } else {
872 false
873 }
874 }
875
876 #[inline(always)]
885 pub fn get_body_string(&self) -> String {
886 String::from_utf8_lossy(self.get_body()).into_owned()
887 }
888
889 pub fn try_get_body_json<T>(&self) -> Result<T, serde_json::Error>
902 where
903 T: DeserializeOwned,
904 {
905 serde_json::from_slice(self.get_body())
906 }
907
908 pub fn get_body_json<T>(&self) -> T
925 where
926 T: DeserializeOwned,
927 {
928 self.try_get_body_json().unwrap()
929 }
930
931 #[inline(always)]
940 pub fn get_string(&self) -> String {
941 let body: &Vec<u8> = self.get_body();
942 let body_type: &'static str = if std::str::from_utf8(body).is_ok() {
943 PLAIN
944 } else {
945 BINARY
946 };
947 format!(
948 "[Request] => [method]: {}; [host]: {}; [version]: {}; [path]: {}; [querys]: {:?}; [headers]: {:?}; [body]: {} bytes {};",
949 self.get_method(),
950 self.get_host(),
951 self.get_version(),
952 self.get_path(),
953 self.get_querys(),
954 self.get_headers(),
955 body.len(),
956 body_type
957 )
958 }
959
960 #[inline(always)]
970 pub fn get_upgrade_type(&self) -> UpgradeType {
971 let upgrade_type: UpgradeType = self
972 .try_get_header_back(UPGRADE)
973 .and_then(|data| data.parse::<UpgradeType>().ok())
974 .unwrap_or_default();
975 upgrade_type
976 }
977
978 #[inline(always)]
986 pub fn is_ws(&self) -> bool {
987 self.get_upgrade_type().is_ws()
988 }
989
990 #[inline(always)]
996 pub fn is_h2c(&self) -> bool {
997 self.get_upgrade_type().is_h2c()
998 }
999
1000 #[inline(always)]
1006 pub fn is_tls(&self) -> bool {
1007 self.get_upgrade_type().is_tls()
1008 }
1009
1010 #[inline(always)]
1016 pub fn is_unknown_upgrade(&self) -> bool {
1017 self.get_upgrade_type().is_unknown()
1018 }
1019
1020 #[inline(always)]
1026 pub fn is_http1_1_or_higher(&self) -> bool {
1027 self.get_version().is_http1_1_or_higher()
1028 }
1029
1030 #[inline(always)]
1036 pub fn is_http0_9(&self) -> bool {
1037 self.get_version().is_http0_9()
1038 }
1039
1040 #[inline(always)]
1046 pub fn is_http1_0(&self) -> bool {
1047 self.get_version().is_http1_0()
1048 }
1049
1050 #[inline(always)]
1056 pub fn is_http1_1(&self) -> bool {
1057 self.get_version().is_http1_1()
1058 }
1059
1060 #[inline(always)]
1066 pub fn is_http2(&self) -> bool {
1067 self.get_version().is_http2()
1068 }
1069
1070 #[inline(always)]
1076 pub fn is_http3(&self) -> bool {
1077 self.get_version().is_http3()
1078 }
1079
1080 #[inline(always)]
1086 pub fn is_unknown_version(&self) -> bool {
1087 self.get_version().is_unknown()
1088 }
1089
1090 #[inline(always)]
1096 pub fn is_http(&self) -> bool {
1097 self.get_version().is_http()
1098 }
1099
1100 #[inline(always)]
1106 pub fn is_get(&self) -> bool {
1107 self.get_method().is_get()
1108 }
1109
1110 #[inline(always)]
1116 pub fn is_post(&self) -> bool {
1117 self.get_method().is_post()
1118 }
1119
1120 #[inline(always)]
1126 pub fn is_put(&self) -> bool {
1127 self.get_method().is_put()
1128 }
1129
1130 #[inline(always)]
1136 pub fn is_delete(&self) -> bool {
1137 self.get_method().is_delete()
1138 }
1139
1140 #[inline(always)]
1146 pub fn is_patch(&self) -> bool {
1147 self.get_method().is_patch()
1148 }
1149
1150 #[inline(always)]
1156 pub fn is_head(&self) -> bool {
1157 self.get_method().is_head()
1158 }
1159
1160 #[inline(always)]
1166 pub fn is_options(&self) -> bool {
1167 self.get_method().is_options()
1168 }
1169
1170 #[inline(always)]
1176 pub fn is_connect(&self) -> bool {
1177 self.get_method().is_connect()
1178 }
1179
1180 #[inline(always)]
1186 pub fn is_trace(&self) -> bool {
1187 self.get_method().is_trace()
1188 }
1189
1190 #[inline(always)]
1196 pub fn is_unknown_method(&self) -> bool {
1197 self.get_method().is_unknown()
1198 }
1199
1200 #[inline(always)]
1216 pub fn is_enable_keep_alive(&self) -> bool {
1217 if let Some(connection_value) = self.try_get_header_back(CONNECTION) {
1218 if connection_value.eq_ignore_ascii_case(KEEP_ALIVE) {
1219 return true;
1220 } else if connection_value.eq_ignore_ascii_case(CLOSE) {
1221 return self.is_ws();
1222 }
1223 }
1224 self.is_http1_1_or_higher() || self.is_ws()
1225 }
1226
1227 #[inline(always)]
1233 pub fn is_disable_keep_alive(&self) -> bool {
1234 !self.is_enable_keep_alive()
1235 }
1236}