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::Unknown(status) => write!(f, "Unknown error occurred [{}]", status.code()),
62 Self::InvalidUrlScheme(status) => write!(f, "Invalid URL scheme [{}]", status.code()),
63 Self::InvalidUrlHost(status) => write!(f, "Invalid URL host [{}]", status.code()),
64 Self::InvalidUrlPort(status) => write!(f, "Invalid URL port [{}]", status.code()),
65 Self::InvalidUrlPath(status) => write!(f, "Invalid URL path [{}]", status.code()),
66 Self::InvalidUrlQuery(status) => write!(f, "Invalid URL query [{}]", status.code()),
67 Self::InvalidUrlFragment(status) => {
68 write!(f, "Invalid URL fragment [{}]", status.code())
69 }
70 Self::ReadTimeoutNotSet(status) => {
71 write!(f, "Failed to set read timeout [{}]", status.code())
72 }
73 Self::WriteTimeoutNotSet(status) => {
74 write!(f, "Failed to set write timeout [{}]", status.code())
75 }
76 Self::TcpConnectionFailed(status) => {
77 write!(f, "Tcp connection failed [{}]", status.code())
78 }
79 Self::TlsHandshakeFailed(status) => {
80 write!(f, "Tls handshake failed [{}]", status.code())
81 }
82 Self::TlsCertificateInvalid(status) => {
83 write!(f, "Tls certificate invalid [{}]", status.code())
84 }
85 Self::WebSocketFrameTooLarge(status) => {
86 write!(f, "WebSocket frame too large [{}]", status.code())
87 }
88 Self::WebSocketOpcodeUnsupported(status) => {
89 write!(f, "WebSocket opcode unsupported [{}]", status.code())
90 }
91 Self::WebSocketMaskMissing(status) => {
92 write!(f, "WebSocket mask missing [{}]", status.code())
93 }
94 Self::WebSocketPayloadCorrupted(status) => {
95 write!(f, "WebSocket payload corrupted [{}]", status.code())
96 }
97 Self::WebSocketInvalidUtf8(status) => {
98 write!(f, "WebSocket invalid UTF-8 [{}]", status.code())
99 }
100 Self::WebSocketInvalidCloseCode(status) => {
101 write!(f, "WebSocket invalid close code [{}]", status.code())
102 }
103 Self::WebSocketInvalidExtension(status) => {
104 write!(f, "WebSocket invalid extension [{}]", status.code())
105 }
106 Self::HttpRequestPartsInsufficient(status) => {
107 write!(f, "HTTP request parts insufficient [{}]", status.code())
108 }
109 }
110 }
111}
112
113impl RequestError {
114 pub fn get_http_status(&self) -> HttpStatus {
126 match self {
127 Self::HttpRead(status) => *status,
128 Self::GetTcpStream(status) => *status,
129 Self::GetTlsStream(status) => *status,
130 Self::ReadConnection(status) => *status,
131 Self::RequestAborted(status) => *status,
132 Self::TlsStreamConnect(status) => *status,
133 Self::NeedOpenRedirect(status) => *status,
134 Self::MaxRedirectTimes(status) => *status,
135 Self::MethodsNotSupport(status) => *status,
136 Self::RedirectInvalidUrl(status) => *status,
137 Self::ClientDisconnected(status) => *status,
138 Self::RedirectUrlDeadLoop(status) => *status,
139 Self::ClientClosedConnection(status) => *status,
140 Self::IncompleteWebSocketFrame(status) => *status,
141 Self::RequestTooLong(status) => *status,
142 Self::PathTooLong(status) => *status,
143 Self::QueryTooLong(status) => *status,
144 Self::HeaderLineTooLong(status) => *status,
145 Self::TooManyHeaders(status) => *status,
146 Self::HeaderKeyTooLong(status) => *status,
147 Self::HeaderValueTooLong(status) => *status,
148 Self::ContentLengthTooLarge(status) => *status,
149 Self::InvalidContentLength(status) => *status,
150 Self::Unknown(status) => *status,
151 Self::InvalidUrlScheme(status) => *status,
152 Self::InvalidUrlHost(status) => *status,
153 Self::InvalidUrlPort(status) => *status,
154 Self::InvalidUrlPath(status) => *status,
155 Self::InvalidUrlQuery(status) => *status,
156 Self::InvalidUrlFragment(status) => *status,
157 Self::ReadTimeoutNotSet(status) => *status,
158 Self::WriteTimeoutNotSet(status) => *status,
159 Self::TcpConnectionFailed(status) => *status,
160 Self::TlsHandshakeFailed(status) => *status,
161 Self::TlsCertificateInvalid(status) => *status,
162 Self::WebSocketFrameTooLarge(status) => *status,
163 Self::WebSocketOpcodeUnsupported(status) => *status,
164 Self::WebSocketMaskMissing(status) => *status,
165 Self::WebSocketPayloadCorrupted(status) => *status,
166 Self::WebSocketInvalidUtf8(status) => *status,
167 Self::WebSocketInvalidCloseCode(status) => *status,
168 Self::WebSocketInvalidExtension(status) => *status,
169 Self::HttpRequestPartsInsufficient(status) => *status,
170 }
171 }
172
173 pub fn get_http_status_code(&self) -> ResponseStatusCode {
185 self.get_http_status().code()
186 }
187}
188
189impl Default for RequestConfig {
190 #[inline(always)]
196 fn default() -> Self {
197 Self {
198 min_buffer_size: KB_2,
199 buffer_size: DEFAULT_BUFFER_SIZE,
200 max_request_line_length: KB_16,
201 max_path_length: KB_8,
202 max_query_length: KB_16,
203 max_header_line_length: KB_16,
204 max_header_count: 200,
205 max_header_key_length: KB_512,
206 max_header_value_length: KB_16,
207 max_body_size: MB_100,
208 max_ws_frame_size: MB_10,
209 max_ws_frames: 5000,
210 http_read_timeout_ms: 60000,
211 ws_read_timeout_ms: 60000,
212 }
213 }
214}
215
216impl RequestConfig {
217 pub fn new() -> Self {
223 Self::default()
224 }
225
226 pub fn high_security() -> Self {
235 Self {
236 min_buffer_size: KB_512,
237 buffer_size: KB_4,
238 max_request_line_length: KB_2,
239 max_path_length: KB_1,
240 max_query_length: KB_2,
241 max_header_line_length: KB_2,
242 max_header_count: 50,
243 max_header_key_length: KB_128,
244 max_header_value_length: KB_2,
245 max_body_size: MB_1,
246 max_ws_frame_size: KB_256,
247 max_ws_frames: 100,
248 http_read_timeout_ms: 10000,
249 ws_read_timeout_ms: 10000,
250 }
251 }
252}
253
254impl Default for Request {
258 #[inline(always)]
259 fn default() -> Self {
260 Self {
261 method: Method::default(),
262 host: String::new(),
263 version: HttpVersion::default(),
264 path: String::new(),
265 querys: hash_map_xx_hash3_64(),
266 headers: hash_map_xx_hash3_64(),
267 body: Vec::new(),
268 }
269 }
270}
271
272impl Request {
273 #[inline(always)]
279 pub fn new() -> Self {
280 Self::default()
281 }
282
283 pub async fn http_from_reader(
296 reader: &mut BufReader<&mut TcpStream>,
297 config: &RequestConfig,
298 ) -> Result<Request, RequestError> {
299 let buffer_size: usize = config.buffer_size.max(config.min_buffer_size);
300 let mut request_line: String = String::with_capacity(buffer_size);
301 let timeout_duration: Duration = Duration::from_millis(config.http_read_timeout_ms);
302 let bytes_read: usize = timeout(
303 timeout_duration,
304 AsyncBufReadExt::read_line(reader, &mut request_line),
305 )
306 .await
307 .map_err(|_| RequestError::ReadTimeoutNotSet(HttpStatus::RequestTimeout))?
308 .map_err(|_| RequestError::HttpRead(HttpStatus::BadRequest))?;
309 if bytes_read > config.max_request_line_length {
310 return Err(RequestError::RequestTooLong(HttpStatus::BadRequest));
311 }
312 let parts: Vec<&str> = request_line.split_whitespace().collect();
313 let parts_len: usize = parts.len();
314 if parts_len < 3 {
315 return Err(RequestError::HttpRequestPartsInsufficient(
316 HttpStatus::BadRequest,
317 ));
318 }
319 let full_path: &str = parts[1];
320 if full_path.len() > config.max_path_length {
321 return Err(RequestError::PathTooLong(HttpStatus::URITooLong));
322 }
323 let method: RequestMethod = parts[0]
324 .parse::<RequestMethod>()
325 .unwrap_or(Method::Unknown(parts[0].to_string()));
326 let full_path: RequestPath = full_path.to_string();
327 let version: RequestVersion = parts[2]
328 .parse::<RequestVersion>()
329 .unwrap_or(RequestVersion::Unknown(parts[2].to_string()));
330 let hash_index: Option<usize> = full_path.find(HASH);
331 let query_index: Option<usize> = full_path.find(QUERY);
332 let query_string: String = query_index.map_or_else(String::new, |i| {
333 let temp: &str = &full_path[i + 1..];
334 if hash_index.is_none() || hash_index.unwrap() <= i {
335 return temp.to_owned();
336 }
337 temp.split(HASH).next().unwrap_or_default().to_owned()
338 });
339 if query_string.len() > config.max_query_length {
340 return Err(RequestError::QueryTooLong(HttpStatus::URITooLong));
341 }
342 let querys: RequestQuerys = Self::parse_querys(&query_string);
343 let path: RequestPath = if let Some(i) = query_index.or(hash_index) {
344 full_path[..i].to_owned()
345 } else {
346 full_path.to_owned()
347 };
348 let mut headers: RequestHeaders = hash_map_xx_hash3_64();
349 let mut host: RequestHost = String::new();
350 let mut content_length: usize = 0;
351 let mut header_count: usize = 0;
352 loop {
353 let mut header_line: String = String::with_capacity(buffer_size);
354 let timeout_duration: Duration = Duration::from_millis(config.http_read_timeout_ms);
355 let bytes_read: usize = timeout(
356 timeout_duration,
357 AsyncBufReadExt::read_line(reader, &mut header_line),
358 )
359 .await
360 .map_err(|_| RequestError::ReadTimeoutNotSet(HttpStatus::RequestTimeout))?
361 .map_err(|_| RequestError::HttpRead(HttpStatus::BadRequest))?;
362 if bytes_read > config.max_header_line_length {
363 return Err(RequestError::HeaderLineTooLong(
364 HttpStatus::RequestHeaderFieldsTooLarge,
365 ));
366 }
367 let header_line: &str = header_line.trim();
368 if header_line.is_empty() {
369 break;
370 }
371 header_count += 1;
372 if header_count > config.max_header_count {
373 return Err(RequestError::TooManyHeaders(
374 HttpStatus::RequestHeaderFieldsTooLarge,
375 ));
376 }
377 if let Some((key_part, value_part)) = header_line.split_once(COLON) {
378 let key: String = key_part.trim().to_ascii_lowercase();
379 if key.is_empty() {
380 continue;
381 }
382 if key.len() > config.max_header_key_length {
383 return Err(RequestError::HeaderKeyTooLong(
384 HttpStatus::RequestHeaderFieldsTooLarge,
385 ));
386 }
387 let value: String = value_part.trim().to_string();
388 if value.len() > config.max_header_value_length {
389 return Err(RequestError::HeaderValueTooLong(
390 HttpStatus::RequestHeaderFieldsTooLarge,
391 ));
392 }
393 if key == HOST {
394 host = value.clone();
395 } else if key == CONTENT_LENGTH {
396 match value.parse::<usize>() {
397 Ok(length) => {
398 if length > config.max_body_size {
399 return Err(RequestError::ContentLengthTooLarge(
400 HttpStatus::PayloadTooLarge,
401 ));
402 }
403 content_length = length;
404 }
405 Err(_) => {
406 return Err(RequestError::InvalidContentLength(HttpStatus::BadRequest));
407 }
408 }
409 }
410 headers.entry(key).or_default().push_back(value);
411 }
412 }
413 let mut body: RequestBody = Vec::with_capacity(content_length);
414 if content_length > 0 {
415 body.resize(content_length, 0);
416 let timeout_duration: Duration = Duration::from_millis(config.http_read_timeout_ms);
417 timeout(
418 timeout_duration,
419 AsyncReadExt::read_exact(reader, &mut body),
420 )
421 .await
422 .map_err(|_| RequestError::ReadTimeoutNotSet(HttpStatus::RequestTimeout))?
423 .map_err(|_| RequestError::ReadConnection(HttpStatus::BadRequest))?;
424 }
425 Ok(Request {
426 method,
427 host,
428 version,
429 path,
430 querys,
431 headers,
432 body,
433 })
434 }
435
436 pub async fn http_from_stream(
449 stream: &ArcRwLockStream,
450 config: &RequestConfig,
451 ) -> Result<Request, RequestError> {
452 let mut buf_stream: RwLockWriteGuard<'_, TcpStream> = stream.write().await;
453 let mut reader: BufReader<&mut TcpStream> = BufReader::new(&mut buf_stream);
454 Self::http_from_reader(&mut reader, config).await
455 }
456
457 pub async fn ws_from_stream(
470 &mut self,
471 stream: &ArcRwLockStream,
472 config: &RequestConfig,
473 ) -> Result<Request, RequestError> {
474 let mut buf_stream: RwLockWriteGuard<'_, TcpStream> = stream.write().await;
475 let mut reader: BufReader<&mut TcpStream> = BufReader::new(&mut buf_stream);
476 self.ws_from_reader(&mut reader, config).await
477 }
478
479 pub async fn ws_from_reader(
493 &mut self,
494 reader: &mut BufReader<&mut TcpStream>,
495 config: &RequestConfig,
496 ) -> Result<Request, RequestError> {
497 let buffer_size: usize = config.buffer_size.max(config.min_buffer_size);
498 let mut dynamic_buffer: Vec<u8> = Vec::with_capacity(buffer_size);
499 let temp_buffer_size: usize = buffer_size;
500 let mut temp_buffer: Vec<u8> = vec![0; temp_buffer_size];
501 let mut full_frame: Vec<u8> = Vec::with_capacity(config.max_ws_frame_size);
502 let mut frame_count: usize = 0;
503 loop {
504 let timeout_duration: Duration = Duration::from_millis(config.ws_read_timeout_ms);
505 let len: usize = match timeout(timeout_duration, reader.read(&mut temp_buffer)).await {
506 Ok(result) => match result {
507 Ok(len) => len,
508 Err(err) => {
509 if err.kind() == ErrorKind::ConnectionReset
510 || err.kind() == ErrorKind::ConnectionAborted
511 {
512 return Err(RequestError::ClientDisconnected(HttpStatus::BadRequest));
513 }
514 return Err(RequestError::Unknown(HttpStatus::InternalServerError));
515 }
516 },
517 Err(_) => {
518 return Err(RequestError::ReadTimeoutNotSet(HttpStatus::RequestTimeout));
519 }
520 };
521 if len == 0 {
522 return Err(RequestError::IncompleteWebSocketFrame(
523 HttpStatus::BadRequest,
524 ));
525 }
526 dynamic_buffer.extend_from_slice(&temp_buffer[..len]);
527 while let Some((frame, consumed)) = WebSocketFrame::decode_ws_frame(&dynamic_buffer) {
528 dynamic_buffer.drain(0..consumed);
529 frame_count += 1;
530 if frame_count > config.max_ws_frames {
531 return Err(RequestError::TooManyHeaders(
532 HttpStatus::RequestHeaderFieldsTooLarge,
533 ));
534 }
535 match frame.get_opcode() {
536 WebSocketOpcode::Close => {
537 return Err(RequestError::ClientClosedConnection(HttpStatus::BadRequest));
538 }
539 WebSocketOpcode::Ping | WebSocketOpcode::Pong => {
540 continue;
541 }
542 WebSocketOpcode::Text | WebSocketOpcode::Binary => {
543 let payload_data: &[u8] = frame.get_payload_data();
544 if payload_data.len() > config.max_ws_frame_size {
545 return Err(RequestError::WebSocketFrameTooLarge(
546 HttpStatus::PayloadTooLarge,
547 ));
548 }
549 if full_frame.len() + payload_data.len() > config.max_ws_frame_size {
550 return Err(RequestError::WebSocketFrameTooLarge(
551 HttpStatus::PayloadTooLarge,
552 ));
553 }
554 full_frame.extend_from_slice(payload_data);
555 if *frame.get_fin() {
556 let mut request: Request = self.clone();
557 request.body = full_frame;
558 return Ok(request);
559 }
560 }
561 _ => {
562 return Err(RequestError::WebSocketOpcodeUnsupported(
563 HttpStatus::NotImplemented,
564 ));
565 }
566 }
567 }
568 }
569 }
570
571 fn parse_querys<Q>(query: Q) -> RequestQuerys
583 where
584 Q: AsRef<str>,
585 {
586 let mut query_map: RequestQuerys = hash_map_xx_hash3_64();
587 for pair in query.as_ref().split(AND) {
588 if let Some((key, value)) = pair.split_once(EQUAL) {
589 if !key.is_empty() {
590 query_map.insert(key.to_string(), value.to_string());
591 }
592 } else if !pair.is_empty() {
593 query_map.insert(pair.to_string(), String::new());
594 }
595 }
596 query_map
597 }
598
599 #[inline(always)]
611 pub fn try_get_query<K>(&self, key: K) -> Option<RequestQuerysValue>
612 where
613 K: AsRef<str>,
614 {
615 self.querys.get(key.as_ref()).cloned()
616 }
617
618 #[inline(always)]
634 pub fn get_query<K>(&self, key: K) -> RequestQuerysValue
635 where
636 K: AsRef<str>,
637 {
638 self.try_get_query(key).unwrap()
639 }
640
641 #[inline(always)]
651 pub fn try_get_header<K>(&self, key: K) -> Option<RequestHeadersValue>
652 where
653 K: AsRef<str>,
654 {
655 self.headers.get(key.as_ref()).cloned()
656 }
657
658 #[inline(always)]
672 pub fn get_header<K>(&self, key: K) -> RequestHeadersValue
673 where
674 K: AsRef<str>,
675 {
676 self.try_get_header(key).unwrap()
677 }
678
679 #[inline(always)]
689 pub fn try_get_header_front<K>(&self, key: K) -> Option<RequestHeadersValueItem>
690 where
691 K: AsRef<str>,
692 {
693 self.headers
694 .get(key.as_ref())
695 .and_then(|values| values.front().cloned())
696 }
697
698 #[inline(always)]
712 pub fn get_header_front<K>(&self, key: K) -> RequestHeadersValueItem
713 where
714 K: AsRef<str>,
715 {
716 self.try_get_header_front(key).unwrap()
717 }
718
719 #[inline(always)]
729 pub fn try_get_header_back<K>(&self, key: K) -> Option<RequestHeadersValueItem>
730 where
731 K: AsRef<str>,
732 {
733 self.headers
734 .get(key.as_ref())
735 .and_then(|values| values.back().cloned())
736 }
737
738 #[inline(always)]
752 pub fn get_header_back<K>(&self, key: K) -> RequestHeadersValueItem
753 where
754 K: AsRef<str>,
755 {
756 self.try_get_header_back(key).unwrap()
757 }
758
759 #[inline(always)]
769 pub fn try_get_header_length<K>(&self, key: K) -> Option<usize>
770 where
771 K: AsRef<str>,
772 {
773 self.headers.get(key.as_ref()).map(|values| values.len())
774 }
775
776 #[inline(always)]
790 pub fn get_header_length<K>(&self, key: K) -> usize
791 where
792 K: AsRef<str>,
793 {
794 self.try_get_header_length(key).unwrap()
795 }
796
797 #[inline(always)]
803 pub fn get_headers_values_length(&self) -> usize {
804 self.headers.values().map(|values| values.len()).sum()
805 }
806
807 #[inline(always)]
813 pub fn get_headers_length(&self) -> usize {
814 self.headers.len()
815 }
816
817 #[inline(always)]
827 pub fn has_header<K>(&self, key: K) -> bool
828 where
829 K: AsRef<str>,
830 {
831 self.headers.contains_key(key.as_ref())
832 }
833
834 #[inline(always)]
845 pub fn has_header_value<K, V>(&self, key: K, value: V) -> bool
846 where
847 K: AsRef<str>,
848 V: AsRef<str>,
849 {
850 if let Some(values) = self.headers.get(key.as_ref()) {
851 values.contains(&value.as_ref().to_owned())
852 } else {
853 false
854 }
855 }
856
857 #[inline(always)]
866 pub fn get_body_string(&self) -> String {
867 String::from_utf8_lossy(self.get_body()).into_owned()
868 }
869
870 pub fn try_get_body_json<T>(&self) -> Result<T, serde_json::Error>
883 where
884 T: DeserializeOwned,
885 {
886 serde_json::from_slice(self.get_body())
887 }
888
889 pub fn get_body_json<T>(&self) -> T
906 where
907 T: DeserializeOwned,
908 {
909 self.try_get_body_json().unwrap()
910 }
911
912 #[inline(always)]
921 pub fn get_string(&self) -> String {
922 let body: &Vec<u8> = self.get_body();
923 let body_type: &'static str = if std::str::from_utf8(body).is_ok() {
924 PLAIN
925 } else {
926 BINARY
927 };
928 format!(
929 "[Request] => [method]: {}; [host]: {}; [version]: {}; [path]: {}; [querys]: {:?}; [headers]: {:?}; [body]: {} bytes {};",
930 self.get_method(),
931 self.get_host(),
932 self.get_version(),
933 self.get_path(),
934 self.get_querys(),
935 self.get_headers(),
936 body.len(),
937 body_type
938 )
939 }
940
941 #[inline(always)]
951 pub fn get_upgrade_type(&self) -> UpgradeType {
952 let upgrade_type: UpgradeType = self
953 .try_get_header_back(UPGRADE)
954 .and_then(|data| data.parse::<UpgradeType>().ok())
955 .unwrap_or_default();
956 upgrade_type
957 }
958
959 #[inline(always)]
967 pub fn is_ws(&self) -> bool {
968 self.get_upgrade_type().is_ws()
969 }
970
971 #[inline(always)]
977 pub fn is_h2c(&self) -> bool {
978 self.get_upgrade_type().is_h2c()
979 }
980
981 #[inline(always)]
987 pub fn is_tls(&self) -> bool {
988 self.get_upgrade_type().is_tls()
989 }
990
991 #[inline(always)]
997 pub fn is_unknown_upgrade(&self) -> bool {
998 self.get_upgrade_type().is_unknown()
999 }
1000
1001 #[inline(always)]
1007 pub fn is_http1_1_or_higher(&self) -> bool {
1008 self.get_version().is_http1_1_or_higher()
1009 }
1010
1011 #[inline(always)]
1017 pub fn is_http0_9(&self) -> bool {
1018 self.get_version().is_http0_9()
1019 }
1020
1021 #[inline(always)]
1027 pub fn is_http1_0(&self) -> bool {
1028 self.get_version().is_http1_0()
1029 }
1030
1031 #[inline(always)]
1037 pub fn is_http1_1(&self) -> bool {
1038 self.get_version().is_http1_1()
1039 }
1040
1041 #[inline(always)]
1047 pub fn is_http2(&self) -> bool {
1048 self.get_version().is_http2()
1049 }
1050
1051 #[inline(always)]
1057 pub fn is_http3(&self) -> bool {
1058 self.get_version().is_http3()
1059 }
1060
1061 #[inline(always)]
1067 pub fn is_unknown_version(&self) -> bool {
1068 self.get_version().is_unknown()
1069 }
1070
1071 #[inline(always)]
1077 pub fn is_http(&self) -> bool {
1078 self.get_version().is_http()
1079 }
1080
1081 #[inline(always)]
1087 pub fn is_get(&self) -> bool {
1088 self.get_method().is_get()
1089 }
1090
1091 #[inline(always)]
1097 pub fn is_post(&self) -> bool {
1098 self.get_method().is_post()
1099 }
1100
1101 #[inline(always)]
1107 pub fn is_put(&self) -> bool {
1108 self.get_method().is_put()
1109 }
1110
1111 #[inline(always)]
1117 pub fn is_delete(&self) -> bool {
1118 self.get_method().is_delete()
1119 }
1120
1121 #[inline(always)]
1127 pub fn is_patch(&self) -> bool {
1128 self.get_method().is_patch()
1129 }
1130
1131 #[inline(always)]
1137 pub fn is_head(&self) -> bool {
1138 self.get_method().is_head()
1139 }
1140
1141 #[inline(always)]
1147 pub fn is_options(&self) -> bool {
1148 self.get_method().is_options()
1149 }
1150
1151 #[inline(always)]
1157 pub fn is_connect(&self) -> bool {
1158 self.get_method().is_connect()
1159 }
1160
1161 #[inline(always)]
1167 pub fn is_trace(&self) -> bool {
1168 self.get_method().is_trace()
1169 }
1170
1171 #[inline(always)]
1177 pub fn is_unknown_method(&self) -> bool {
1178 self.get_method().is_unknown()
1179 }
1180
1181 #[inline(always)]
1197 pub fn is_enable_keep_alive(&self) -> bool {
1198 if let Some(connection_value) = self.try_get_header_back(CONNECTION) {
1199 if connection_value.eq_ignore_ascii_case(KEEP_ALIVE) {
1200 return true;
1201 } else if connection_value.eq_ignore_ascii_case(CLOSE) {
1202 return self.is_ws();
1203 }
1204 }
1205 self.is_http1_1_or_higher() || self.is_ws()
1206 }
1207
1208 #[inline(always)]
1214 pub fn is_disable_keep_alive(&self) -> bool {
1215 !self.is_enable_keep_alive()
1216 }
1217}