http_type/response/impl.rs
1use super::*;
2
3/// Implements the `std::error::Error` trait for `ResponseError`.
4/// This allows `ResponseError` to be treated as a standard Rust error type.
5impl Error for ResponseError {}
6
7/// Converts an I/O error to a `ResponseError`.
8///
9/// Maps I/O errors to `Send` variant with the error message.
10impl From<io::Error> for ResponseError {
11 /// Converts an I/O error to a `ResponseError`.
12 ///
13 /// # Arguments
14 ///
15 /// - `io::Error` - The I/O error to convert.
16 ///
17 /// # Returns
18 ///
19 /// - `ResponseError` - The corresponding response error as `Send`.
20 #[inline(always)]
21 fn from(error: io::Error) -> Self {
22 ResponseError::Send(error.to_string())
23 }
24}
25
26/// Implements the `Display` trait for `ResponseError`.
27/// This allows `ResponseError` variants to be formatted into human-readable strings.
28impl Display for ResponseError {
29 /// Formats the `ResponseError` variant into a human-readable string.
30 ///
31 /// # Arguments
32 ///
33 /// - `&mut Formatter<'_>` - The formatter used for writing the formatted string.
34 ///
35 /// # Returns
36 ///
37 /// A `fmt::Result` indicating whether the formatting was successful.
38 #[inline(always)]
39 fn fmt(&self, data: &mut Formatter<'_>) -> fmt::Result {
40 match self {
41 Self::NotFoundStream => {
42 write!(data, "Not found stream")
43 }
44 Self::ConnectionClosed => {
45 write!(data, "Connection has been closed")
46 }
47 Self::Terminated => {
48 write!(data, "Current processing has been terminated")
49 }
50 Self::Send(error) => write!(data, "Send error{COLON_SPACE}{error}"),
51 Self::FlushError(error) => write!(data, "Flush error{COLON_SPACE}{error}"),
52 Self::Unknown => write!(data, "Unknown error"),
53 }
54 }
55}
56
57/// Provides a default value for `Response`.
58///
59/// Returns a new `Response` instance with all fields initialized to their default values.
60impl Default for Response {
61 /// Builds the default `Response` with all fields set to their defaults.
62 #[inline(always)]
63 fn default() -> Self {
64 let http_status: HttpStatus = HttpStatus::default();
65 Self {
66 version: HttpVersion::Http1_1,
67 status_code: http_status.code(),
68 reason_phrase: http_status.to_string(),
69 headers: hash_map_xx_hash3_64(),
70 body: Vec::new(),
71 }
72 }
73}
74
75impl Response {
76 /// Pushes a header with a key and value as_ref the response string.
77 ///
78 /// # Arguments
79 ///
80 /// - `&mut String` - A mutable reference to the string where the header will be added.
81 /// - `&str` - The header key as a string slice (`&str`).
82 /// - `&str` - The header value as a string slice (`&str`).
83 #[inline(always)]
84 fn push_header(response_string: &mut String, key: &str, value: &str) {
85 response_string.push_str(key);
86 response_string.push_str(COLON);
87 response_string.push_str(value);
88 response_string.push_str(HTTP_BR);
89 }
90
91 /// Tries to retrieve the value of a response header by its key.
92 ///
93 /// # Arguments
94 ///
95 /// - `K` - The header's key, which must implement `AsRef<str>`.
96 ///
97 /// # Returns
98 ///
99 /// - `Option<ResponseHeadersValue>` - The optional header values.
100 #[inline(always)]
101 pub fn try_get_header<K>(&self, key: K) -> Option<ResponseHeadersValue>
102 where
103 K: AsRef<str>,
104 {
105 self.headers.get(key.as_ref()).cloned()
106 }
107
108 /// Retrieves the value of a response header by its key.
109 ///
110 /// # Arguments
111 ///
112 /// - `K` - The header's key, which must implement `AsRef<str>`.
113 ///
114 /// # Returns
115 ///
116 /// - `ResponseHeadersValue` - The optional header values.
117 ///
118 /// # Panics
119 ///
120 /// This function will panic if the header key is not found.
121 #[inline(always)]
122 pub fn get_header<K>(&self, key: K) -> ResponseHeadersValue
123 where
124 K: AsRef<str>,
125 {
126 self.try_get_header(key).unwrap()
127 }
128
129 /// Tries to retrieve the first value of a response header by its key.
130 ///
131 /// # Arguments
132 ///
133 /// - `K` - The header's key, which must implement `AsRef<str>`.
134 ///
135 /// # Returns
136 ///
137 /// - `Option<ResponseHeadersValueItem>` - The first header value if exists.
138 #[inline(always)]
139 pub fn try_get_header_front<K>(&self, key: K) -> Option<ResponseHeadersValueItem>
140 where
141 K: AsRef<str>,
142 {
143 self.headers
144 .get(key.as_ref())
145 .and_then(|data: &VecDeque<String>| data.front().cloned())
146 }
147
148 /// Retrieves the first value of a response header by its key.
149 ///
150 /// # Arguments
151 ///
152 /// - `K` - The header's key, which must implement `AsRef<str>`.
153 ///
154 /// # Returns
155 ///
156 /// - `ResponseHeadersValueItem` - The first header value if exists.
157 ///
158 /// # Panics
159 ///
160 /// This function will panic if the header key is not found.
161 #[inline(always)]
162 pub fn get_header_front<K>(&self, key: K) -> ResponseHeadersValueItem
163 where
164 K: AsRef<str>,
165 {
166 self.try_get_header_front(key).unwrap()
167 }
168
169 /// Tries to retrieve the last value of a response header by its key.
170 ///
171 /// # Arguments
172 ///
173 /// - `K` - The header's key, which must implement `AsRef<str>`.
174 ///
175 /// # Returns
176 ///
177 /// - `Option<ResponseHeadersValueItem>` - The last header value if exists.
178 #[inline(always)]
179 pub fn try_get_header_back<K>(&self, key: K) -> Option<ResponseHeadersValueItem>
180 where
181 K: AsRef<str>,
182 {
183 self.headers
184 .get(key.as_ref())
185 .and_then(|data: &VecDeque<String>| data.back().cloned())
186 }
187
188 /// Retrieves the last value of a response header by its key.
189 ///
190 /// # Arguments
191 ///
192 /// - `K` - The header's key, which must implement `AsRef<str>`.
193 ///
194 /// # Returns
195 ///
196 /// - `ResponseHeadersValueItem` - The last header value if exists.
197 ///
198 /// # Panics
199 ///
200 /// This function will panic if the header key is not found.
201 #[inline(always)]
202 pub fn get_header_back<K>(&self, key: K) -> ResponseHeadersValueItem
203 where
204 K: AsRef<str>,
205 {
206 self.try_get_header_back(key).unwrap()
207 }
208
209 /// Checks if a header exists in the response.
210 ///
211 /// # Arguments
212 ///
213 /// - `K` - The header key to check, which must implement `AsRef<str>`.
214 ///
215 /// # Returns
216 ///
217 /// - `bool` - Whether the header exists.
218 #[inline(always)]
219 pub fn has_header<K>(&self, key: K) -> bool
220 where
221 K: AsRef<str>,
222 {
223 self.get_headers().contains_key(key.as_ref())
224 }
225
226 /// Checks if a header contains a specific value.
227 ///
228 /// # Arguments
229 ///
230 /// - `K` - The header key to check, which must implement `AsRef<str>`.
231 /// - `V` - The value to search for, which must implement `AsRef<str>`.
232 ///
233 /// # Returns
234 ///
235 /// - `bool` - Whether the header contains the value.
236 #[inline(always)]
237 pub fn has_header_value<K, V>(&self, key: K, value: V) -> bool
238 where
239 K: AsRef<str>,
240 V: AsRef<str>,
241 {
242 if let Some(values) = self.get_headers().get(key.as_ref()) {
243 values.contains(&value.as_ref().to_owned())
244 } else {
245 false
246 }
247 }
248
249 /// Gets the number of headers in the response.
250 ///
251 /// # Returns
252 ///
253 /// - `usize` - The count of unique header keys.
254 #[inline(always)]
255 pub fn get_headers_size(&self) -> usize {
256 self.headers.len()
257 }
258
259 /// Tries to get the number of values for a specific header key.
260 ///
261 /// # Arguments
262 ///
263 /// - `K` - The header key to count, which must implement `AsRef<str>`.
264 ///
265 /// # Returns
266 ///
267 /// - `Option<usize>` - The count of values for the header.
268 #[inline(always)]
269 pub fn try_get_header_size<K>(&self, key: K) -> Option<usize>
270 where
271 K: AsRef<str>,
272 {
273 self.headers
274 .get(key.as_ref())
275 .map(|data: &VecDeque<String>| data.len())
276 }
277
278 /// Gets the number of values for a specific header key.
279 ///
280 /// # Arguments
281 ///
282 /// - `K` - The header key to count, which must implement `AsRef<str>`.
283 ///
284 /// # Returns
285 ///
286 /// - `usize` - The count of values for the header.
287 ///
288 /// # Panics
289 ///
290 /// This function will panic if the header key is not found.
291 #[inline(always)]
292 pub fn get_header_size<K>(&self, key: K) -> usize
293 where
294 K: AsRef<str>,
295 {
296 self.try_get_header_size(key).unwrap()
297 }
298
299 /// Gets the total number of header values in the response.
300 ///
301 /// This counts all values across all headers, so a header with multiple values
302 /// will contribute more than one to the total count.
303 ///
304 /// # Returns
305 ///
306 /// - `usize` - The total count of all header values.
307 #[inline(always)]
308 pub fn get_headers_values_size(&self) -> usize {
309 self.headers
310 .values()
311 .map(|data: &VecDeque<String>| data.len())
312 .sum()
313 }
314
315 /// Retrieves the body content of the response as a UTF-8 encoded string.
316 ///
317 /// This method uses `String::from_utf8_lossy` to convert the byte slice returned by `self.get_body()` as_ref a string.
318 /// If the byte slice contains invalid UTF-8 sequences, they will be replaced with the Unicode replacement character ().
319 ///
320 /// # Returns
321 ///
322 /// - `String` - The body content as a string.
323 #[inline(always)]
324 pub fn get_body_string(&self) -> String {
325 String::from_utf8_lossy(self.get_body()).into_owned()
326 }
327
328 /// Deserializes the body content of the response as_ref a specified type `T`.
329 ///
330 /// This method first retrieves the body content as a byte slice using `self.get_body()`.
331 /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
332 ///
333 /// The target type `T` is a type parameter of this method and must implement `DeserializeOwned`.
334 ///
335 /// # Returns
336 ///
337 /// - `Result<T, serde_json::Error>` - The deserialization result.
338 pub fn try_get_body_json<T>(&self) -> Result<T, serde_json::Error>
339 where
340 T: DeserializeOwned,
341 {
342 serde_json::from_slice(self.get_body())
343 }
344
345 /// Deserializes the body content of the response as_ref a specified type `T`.
346 ///
347 /// This method first retrieves the body content as a byte slice using `self.get_body()`.
348 /// It then attempts to deserialize the byte slice as_ref the specified type `T` using `json_from_slice`.
349 ///
350 /// The target type `T` is a type parameter of this method and must implement `DeserializeOwned`.
351 ///
352 /// # Returns
353 ///
354 /// - `T` - The deserialized body content.
355 ///
356 /// # Panics
357 ///
358 /// This function will panic if the deserialization fails.
359 pub fn get_body_json<T>(&self) -> T
360 where
361 T: DeserializeOwned,
362 {
363 self.try_get_body_json().unwrap()
364 }
365
366 /// Determines whether the header should be skipped during setting.
367 ///
368 /// # Arguments
369 ///
370 /// - `&ResponseHeadersKey` - The header key to inspect.
371 ///
372 /// # Returns
373 ///
374 /// - `bool` - `true` if the header is empty or not allowed, `false` if the header can be set.
375 #[inline(always)]
376 fn should_skip_header(&self, key: &ResponseHeadersKey) -> bool {
377 key.trim().is_empty() || key == CONTENT_LENGTH
378 }
379
380 /// Sets a header in the response, replacing any existing values.
381 ///
382 /// This function replaces all existing values for a header with a single new value.
383 ///
384 /// # Arguments
385 ///
386 /// - `K` - The header key, which must implement `AsRef<str>`.
387 /// - `V` - The header value, which must implement `AsRef<String>`.
388 ///
389 /// # Returns
390 ///
391 /// - `&mut Self` - A mutable reference to self for chaining.
392 #[inline(always)]
393 fn set_header_without_check<K, V>(&mut self, key: K, value: V) -> &mut Self
394 where
395 K: AsRef<str>,
396 V: AsRef<str>,
397 {
398 let mut deque: VecDeque<String> = VecDeque::with_capacity(1);
399 deque.push_back(value.as_ref().to_owned());
400 self.get_mut_headers()
401 .insert(key.as_ref().to_owned(), deque);
402 self
403 }
404
405 /// Sets a header in the response, replacing any existing values.
406 ///
407 /// This function replaces all existing values for a header with a single new value.
408 ///
409 /// # Arguments
410 ///
411 /// - `K` - The header key, which must implement `AsRef<str>`.
412 /// - `V` - The header value, which must implement `AsRef<String>`.
413 ///
414 /// # Returns
415 ///
416 /// - `&mut Self` - A mutable reference to self for chaining.
417 #[inline(always)]
418 pub fn set_header<K, V>(&mut self, key: K, value: V) -> &mut Self
419 where
420 K: AsRef<str>,
421 V: AsRef<str>,
422 {
423 let key: ResponseHeadersKey = key.as_ref().to_owned();
424 if self.should_skip_header(&key) {
425 return self;
426 }
427 let mut deque: VecDeque<String> = VecDeque::with_capacity(1);
428 deque.push_back(value.as_ref().to_owned());
429 self.headers.insert(key, deque);
430 self
431 }
432
433 /// Adds a header to the response.
434 ///
435 /// This function appends a value to the response headers.
436 /// If the header already exists, the new value will be added to the existing values.
437 ///
438 /// # Arguments
439 ///
440 /// - `K` - The header key, which must implement `AsRef<str>`.
441 /// - `V` - The header value, which must implement `AsRef<String>`.
442 ///
443 /// # Returns
444 ///
445 /// - `&mut Self` - A mutable reference to self for chaining.
446 #[inline(always)]
447 pub fn add_header<K, V>(&mut self, key: K, value: V) -> &mut Self
448 where
449 K: AsRef<str>,
450 V: AsRef<str>,
451 {
452 let key: ResponseHeadersKey = key.as_ref().to_owned();
453 if self.should_skip_header(&key) {
454 return self;
455 }
456 self.get_mut_headers()
457 .entry(key)
458 .or_default()
459 .push_back(value.as_ref().to_owned());
460 self
461 }
462
463 /// Removes a header from the response.
464 ///
465 /// This function removes all values for the specified header key.
466 ///
467 /// # Arguments
468 ///
469 /// - `K` - The header key to remove, which must implement `AsRef<str>`.
470 ///
471 /// # Returns
472 ///
473 /// - `&mut Self` - A mutable reference to self for chaining.
474 #[inline(always)]
475 pub fn remove_header<K>(&mut self, key: K) -> &mut Self
476 where
477 K: AsRef<str>,
478 {
479 let _: bool = self.get_mut_headers().remove(key.as_ref()).is_some();
480 self
481 }
482
483 /// Removes a specific value from a header in the response.
484 ///
485 /// This function removes only the specified value from the header.
486 /// If the header has multiple values, only the matching value is removed.
487 /// If this was the last value for the header, the entire header is removed.
488 ///
489 /// # Arguments
490 ///
491 /// - `K` - The header key, which must implement `AsRef<str>`.
492 /// - `V` - The value to remove, which must implement `AsRef<String>`.
493 ///
494 /// # Returns
495 ///
496 /// - `&mut Self` - A mutable reference to self for chaining.
497 #[inline(always)]
498 pub fn remove_header_value<K, V>(&mut self, key: K, value: V) -> &mut Self
499 where
500 K: AsRef<str>,
501 V: AsRef<str>,
502 {
503 let key: ResponseHeadersKey = key.as_ref().to_owned();
504 if let Some(values) = self.get_mut_headers().get_mut(&key) {
505 values.retain(|data: &String| data != &value.as_ref().to_owned());
506 if values.is_empty() {
507 self.get_mut_headers().remove(&key);
508 }
509 }
510 self
511 }
512
513 /// Clears all headers from the response.
514 ///
515 /// This function removes all headers, leaving the headers map empty.
516 ///
517 /// # Returns
518 ///
519 /// - `&mut Self` - A mutable reference to self for chaining.
520 #[inline(always)]
521 pub fn clear_headers(&mut self) -> &mut Self {
522 self.get_mut_headers().clear();
523 self
524 }
525
526 /// Resets the response to its default state while retaining allocated capacity.
527 ///
528 /// This keeps the header map and body allocations so persistent
529 /// (keep-alive) connections avoid repeated allocation per request.
530 ///
531 /// # Returns
532 ///
533 /// - `&mut Self` - A mutable reference to self for chaining.
534 pub fn reset(&mut self) -> &mut Self {
535 let http_status: HttpStatus = HttpStatus::default();
536 self.set_status_code(http_status.code());
537 self.get_mut_reason_phrase().clear();
538 let _: fmt::Result = write!(self.get_mut_reason_phrase(), "{}", http_status);
539 self.get_mut_headers().clear();
540 self.get_mut_body().clear();
541 self
542 }
543
544 /// Tries to parse cookies from the `Set-Cookie` header.
545 ///
546 /// This method retrieves the last `Set-Cookie` header value and parses it
547 /// into a collection of key-value pairs representing the cookies.
548 ///
549 /// # Returns
550 ///
551 /// - `Option<Cookies>` - The parsed cookies if the `Set-Cookie` header exists, otherwise `None`.
552 #[inline(always)]
553 pub fn try_get_cookies(&self) -> Option<Cookies> {
554 self.try_get_header_back(SET_COOKIE)
555 .map(|cookie_header: String| Cookie::parse(cookie_header))
556 }
557
558 /// Parses cookies from the `Set-Cookie` headers.
559 ///
560 /// This method retrieves all `Set-Cookie` header values and parses each one
561 /// into a collection of key-value pairs representing the cookies.
562 ///
563 /// # Returns
564 ///
565 /// - `Cookies` - The parsed cookies.
566 ///
567 /// # Panics
568 ///
569 /// This function will panic if the `Set-Cookie` header is not found.
570 #[inline(always)]
571 pub fn get_cookies(&self) -> Cookies {
572 self.try_get_cookies().unwrap()
573 }
574
575 /// Tries to get a cookie value by its key from `Set-Cookie` headers.
576 ///
577 /// This method parses the cookies from all `Set-Cookie` headers,
578 /// then attempts to retrieve the value for the specified key.
579 ///
580 /// # Arguments
581 ///
582 /// - `K` - The cookie key, which implements `AsRef<str>`.
583 ///
584 /// # Returns
585 ///
586 /// - `Option<CookieValue>` - The cookie value if exists.
587 #[inline(always)]
588 pub fn try_get_cookie<K>(&self, key: K) -> Option<CookieValue>
589 where
590 K: AsRef<str>,
591 {
592 self.try_get_cookies()
593 .and_then(|cookies: Cookies| cookies.get(key.as_ref()).cloned())
594 }
595
596 /// Gets a cookie value by its key from `Set-Cookie` headers.
597 ///
598 /// This method parses the cookies from all `Set-Cookie` headers,
599 /// then retrieves the value for the specified key.
600 ///
601 /// # Arguments
602 ///
603 /// - `K` - The cookie key, which implements `AsRef<str>`.
604 ///
605 /// # Returns
606 ///
607 /// - `CookieValue` - The cookie value.
608 ///
609 /// # Panics
610 ///
611 /// This function will panic if the `Set-Cookie` header is not found
612 /// or the cookie key does not exist.
613 #[inline(always)]
614 pub fn get_cookie<K>(&self, key: K) -> CookieValue
615 where
616 K: AsRef<str>,
617 {
618 self.try_get_cookie(key).unwrap()
619 }
620
621 /// Builds the full HTTP response as a byte vector.
622 ///
623 /// This method constructs the complete HTTP response, including the status line,
624 /// headers, and body. It handles content encoding, content type, connection
625 /// management, and content length.
626 ///
627 /// # Returns
628 ///
629 /// - `ResponseData` - The complete HTTP response bytes.
630 pub fn build(&mut self) -> ResponseData {
631 if self.get_reason_phrase().is_empty() {
632 self.set_reason_phrase(HttpStatus::phrase(self.get_status_code()));
633 }
634 let compress_type_opt: Option<Compress> = self
635 .try_get_header_back(CONTENT_ENCODING)
636 .map(|data: String| data.parse::<Compress>().unwrap_or_default());
637 if self.try_get_header_back(CONNECTION).is_none() {
638 self.set_header_without_check(CONNECTION, KEEP_ALIVE);
639 }
640 let content_type: ResponseHeadersValueItem =
641 self.try_get_header_back(CONTENT_TYPE).unwrap_or_else(|| {
642 let mut content_type: String = String::with_capacity(
643 TEXT_HTML.len() + SEMICOLON_SPACE.len() + CHARSET_UTF_8.len(),
644 );
645 content_type.push_str(TEXT_HTML);
646 content_type.push_str(SEMICOLON_SPACE);
647 content_type.push_str(CHARSET_UTF_8);
648 self.set_header_without_check(CONTENT_TYPE, &content_type);
649 content_type
650 });
651 let compressed_body: Option<Vec<u8>> = match compress_type_opt {
652 Some(compress_type) if !compress_type.is_unknown() => Some(
653 compress_type
654 .encode(self.get_body(), DEFAULT_BUFFER_SIZE)
655 .into_owned(),
656 ),
657 _ => None,
658 };
659 let body_len: usize = compressed_body
660 .as_ref()
661 .map_or_else(|| self.get_body().len(), Vec::len);
662 if !content_type.eq_ignore_ascii_case(TEXT_EVENT_STREAM) {
663 self.set_header_without_check(CONTENT_LENGTH, body_len.to_string());
664 }
665 let mut head_size: usize = self.get_reason_phrase().len() + B_16 + HTTP_BR.len();
666 head_size += self
667 .get_headers()
668 .iter()
669 .map(|header_entry: (&String, &VecDeque<String>)| {
670 let (header_key, header_values): (&String, &VecDeque<String>) = header_entry;
671 header_values
672 .iter()
673 .map(|header_value: &String| {
674 header_key.len() + COLON.len() + header_value.len() + HTTP_BR.len()
675 })
676 .sum::<usize>()
677 })
678 .sum::<usize>();
679 let mut response_string: String = String::with_capacity(head_size + body_len);
680 let _: fmt::Result = write!(
681 response_string,
682 "{} {} {}{HTTP_BR}",
683 self.get_version(),
684 self.get_status_code(),
685 self.get_reason_phrase()
686 );
687 self.get_headers()
688 .iter()
689 .for_each(|header_entry: (&String, &VecDeque<String>)| {
690 let (header_key, header_values): (&String, &VecDeque<String>) = header_entry;
691 for header_value in header_values.iter() {
692 Self::push_header(&mut response_string, header_key, header_value);
693 }
694 });
695 response_string.push_str(HTTP_BR);
696 let mut response_bytes: Vec<u8> = response_string.into_bytes();
697 match &compressed_body {
698 Some(body) => response_bytes.extend_from_slice(body),
699 None => response_bytes.extend_from_slice(self.get_body()),
700 }
701 response_bytes
702 }
703}