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 // A recycled entry carries the buffers of the name and of the value,
399 // so a response that sets the same headers over and over stops
400 // allocating for them.
401 let (mut name, mut values): (String, VecDeque<String>) =
402 take_header_entry().unwrap_or_else(|| (String::new(), VecDeque::new()));
403 name.clear();
404 name.push_str(key.as_ref());
405 // A recycled entry may carry the values of a header that was sent
406 // more than once. Those values belong to that header, so only the
407 // first one is kept and the rest are dropped.
408 while values.len() > 1 {
409 values.pop_back();
410 }
411 if values.is_empty() {
412 values.push_back(String::new());
413 }
414 if let Some(slot) = values.front_mut() {
415 slot.clear();
416 slot.push_str(value.as_ref());
417 }
418 self.get_mut_headers().insert(name, values);
419 self
420 }
421
422 /// Sets a header in the response, replacing any existing values.
423 ///
424 /// This function replaces all existing values for a header with a single new value.
425 ///
426 /// # Arguments
427 ///
428 /// - `K` - The header key, which must implement `AsRef<str>`.
429 /// - `V` - The header value, which must implement `AsRef<String>`.
430 ///
431 /// # Returns
432 ///
433 /// - `&mut Self` - A mutable reference to self for chaining.
434 #[inline(always)]
435 pub fn set_header<K, V>(&mut self, key: K, value: V) -> &mut Self
436 where
437 K: AsRef<str>,
438 V: AsRef<str>,
439 {
440 let key: ResponseHeadersKey = key.as_ref().to_owned();
441 if self.should_skip_header(&key) {
442 return self;
443 }
444 let mut deque: VecDeque<String> = VecDeque::with_capacity(1);
445 deque.push_back(value.as_ref().to_owned());
446 self.headers.insert(key, deque);
447 self
448 }
449
450 /// Adds a header to the response.
451 ///
452 /// This function appends a value to the response headers.
453 /// If the header already exists, the new value will be added to the existing values.
454 ///
455 /// # Arguments
456 ///
457 /// - `K` - The header key, which must implement `AsRef<str>`.
458 /// - `V` - The header value, which must implement `AsRef<String>`.
459 ///
460 /// # Returns
461 ///
462 /// - `&mut Self` - A mutable reference to self for chaining.
463 #[inline(always)]
464 pub fn add_header<K, V>(&mut self, key: K, value: V) -> &mut Self
465 where
466 K: AsRef<str>,
467 V: AsRef<str>,
468 {
469 let key: ResponseHeadersKey = key.as_ref().to_owned();
470 if self.should_skip_header(&key) {
471 return self;
472 }
473 self.get_mut_headers()
474 .entry(key)
475 .or_default()
476 .push_back(value.as_ref().to_owned());
477 self
478 }
479
480 /// Removes a header from the response.
481 ///
482 /// This function removes all values for the specified header key.
483 ///
484 /// # Arguments
485 ///
486 /// - `K` - The header key to remove, which must implement `AsRef<str>`.
487 ///
488 /// # Returns
489 ///
490 /// - `&mut Self` - A mutable reference to self for chaining.
491 #[inline(always)]
492 pub fn remove_header<K>(&mut self, key: K) -> &mut Self
493 where
494 K: AsRef<str>,
495 {
496 let _: bool = self.get_mut_headers().remove(key.as_ref()).is_some();
497 self
498 }
499
500 /// Removes a specific value from a header in the response.
501 ///
502 /// This function removes only the specified value from the header.
503 /// If the header has multiple values, only the matching value is removed.
504 /// If this was the last value for the header, the entire header is removed.
505 ///
506 /// # Arguments
507 ///
508 /// - `K` - The header key, which must implement `AsRef<str>`.
509 /// - `V` - The value to remove, which must implement `AsRef<String>`.
510 ///
511 /// # Returns
512 ///
513 /// - `&mut Self` - A mutable reference to self for chaining.
514 #[inline(always)]
515 pub fn remove_header_value<K, V>(&mut self, key: K, value: V) -> &mut Self
516 where
517 K: AsRef<str>,
518 V: AsRef<str>,
519 {
520 let key: ResponseHeadersKey = key.as_ref().to_owned();
521 if let Some(values) = self.get_mut_headers().get_mut(&key) {
522 values.retain(|data: &String| data != &value.as_ref().to_owned());
523 if values.is_empty() {
524 self.get_mut_headers().remove(&key);
525 }
526 }
527 self
528 }
529
530 /// Clears all headers from the response.
531 ///
532 /// This function removes all headers, leaving the headers map empty.
533 ///
534 /// # Returns
535 ///
536 /// - `&mut Self` - A mutable reference to self for chaining.
537 #[inline(always)]
538 pub fn clear_headers(&mut self) -> &mut Self {
539 self.get_mut_headers().clear();
540 self
541 }
542
543 /// Resets the response to its default state while retaining allocated capacity.
544 ///
545 /// This keeps the header map and body allocations so persistent
546 /// (keep-alive) connections avoid repeated allocation per request.
547 ///
548 /// # Returns
549 ///
550 /// - `&mut Self` - A mutable reference to self for chaining.
551 pub fn reset(&mut self) -> &mut Self {
552 let http_status: HttpStatus = HttpStatus::default();
553 self.set_status_code(http_status.code());
554 self.get_mut_reason_phrase().clear();
555 let _: fmt::Result = write!(self.get_mut_reason_phrase(), "{}", http_status);
556 self.recycle_headers();
557 self.get_mut_body().clear();
558 self
559 }
560
561 /// Hands the header entries to the pool and empties the header map.
562 ///
563 /// The map ends up empty, exactly as clearing it would, but the name and
564 /// the value buffers of every header survive in the pool. The next
565 /// response reuses them instead of allocating new ones.
566 ///
567 /// # Returns
568 ///
569 /// - `()` - The headers have been recycled.
570 fn recycle_headers(&mut self) {
571 let headers: &mut ResponseHeaders = self.get_mut_headers();
572 if headers.is_empty() {
573 return;
574 }
575 for (key, values) in headers.drain() {
576 return_header_entry((key, values));
577 }
578 }
579
580 /// Tries to parse cookies from the `Set-Cookie` header.
581 ///
582 /// This method retrieves the last `Set-Cookie` header value and parses it
583 /// into a collection of key-value pairs representing the cookies.
584 ///
585 /// # Returns
586 ///
587 /// - `Option<Cookies>` - The parsed cookies if the `Set-Cookie` header exists, otherwise `None`.
588 #[inline(always)]
589 pub fn try_get_cookies(&self) -> Option<Cookies> {
590 self.try_get_header_back(SET_COOKIE)
591 .map(|cookie_header: String| Cookie::parse(cookie_header))
592 }
593
594 /// Parses cookies from the `Set-Cookie` headers.
595 ///
596 /// This method retrieves all `Set-Cookie` header values and parses each one
597 /// into a collection of key-value pairs representing the cookies.
598 ///
599 /// # Returns
600 ///
601 /// - `Cookies` - The parsed cookies.
602 ///
603 /// # Panics
604 ///
605 /// This function will panic if the `Set-Cookie` header is not found.
606 #[inline(always)]
607 pub fn get_cookies(&self) -> Cookies {
608 self.try_get_cookies().unwrap()
609 }
610
611 /// Tries to get a cookie value by its key from `Set-Cookie` headers.
612 ///
613 /// This method parses the cookies from all `Set-Cookie` headers,
614 /// then attempts to retrieve the value for the specified key.
615 ///
616 /// # Arguments
617 ///
618 /// - `K` - The cookie key, which implements `AsRef<str>`.
619 ///
620 /// # Returns
621 ///
622 /// - `Option<CookieValue>` - The cookie value if exists.
623 #[inline(always)]
624 pub fn try_get_cookie<K>(&self, key: K) -> Option<CookieValue>
625 where
626 K: AsRef<str>,
627 {
628 self.try_get_cookies()
629 .and_then(|cookies: Cookies| cookies.get(key.as_ref()).cloned())
630 }
631
632 /// Gets a cookie value by its key from `Set-Cookie` headers.
633 ///
634 /// This method parses the cookies from all `Set-Cookie` headers,
635 /// then retrieves the value for the specified key.
636 ///
637 /// # Arguments
638 ///
639 /// - `K` - The cookie key, which implements `AsRef<str>`.
640 ///
641 /// # Returns
642 ///
643 /// - `CookieValue` - The cookie value.
644 ///
645 /// # Panics
646 ///
647 /// This function will panic if the `Set-Cookie` header is not found
648 /// or the cookie key does not exist.
649 #[inline(always)]
650 pub fn get_cookie<K>(&self, key: K) -> CookieValue
651 where
652 K: AsRef<str>,
653 {
654 self.try_get_cookie(key).unwrap()
655 }
656
657 /// Builds the full HTTP response as a byte vector.
658 ///
659 /// This method constructs the complete HTTP response, including the status line,
660 /// headers, and body. It handles content encoding, content type, connection
661 /// management, and content length.
662 ///
663 /// # Returns
664 ///
665 /// - `ResponseData` - The complete HTTP response bytes.
666 pub fn build(&mut self) -> ResponseData {
667 if self.get_reason_phrase().is_empty() || self.get_reason_phrase().as_str() == OK {
668 self.set_reason_phrase(HttpStatus::phrase(self.get_status_code()));
669 }
670 let compress_type_opt: Option<Compress> = self
671 .try_get_header_back(CONTENT_ENCODING)
672 .map(|data: String| data.parse::<Compress>().unwrap_or_default());
673 if self.try_get_header_back(CONNECTION).is_none() {
674 self.set_header_without_check(CONNECTION, KEEP_ALIVE);
675 }
676 let owned_content_type: Option<String> = self.try_get_header_back(CONTENT_TYPE);
677 let content_type: &str = match owned_content_type {
678 Some(ref value) => value.as_str(),
679 None => {
680 let default: &str = default_content_type();
681 self.set_header_without_check(CONTENT_TYPE, default);
682 default
683 }
684 };
685 let compressed_body: Option<Vec<u8>> = match compress_type_opt {
686 Some(compress_type) if !compress_type.is_unknown() => Some(
687 compress_type
688 .encode(self.get_body(), DEFAULT_BUFFER_SIZE)
689 .into_owned(),
690 ),
691 _ => None,
692 };
693 let body_len: usize = compressed_body
694 .as_ref()
695 .map_or_else(|| self.get_body().len(), Vec::len);
696 if !content_type.eq_ignore_ascii_case(TEXT_EVENT_STREAM) {
697 // The length is written into a pooled string, so announcing it
698 // does not allocate a fresh one for every response.
699 let mut length: String = take_recycled_string().unwrap_or_default();
700 length.clear();
701 let _: fmt::Result = write!(length, "{body_len}");
702 self.set_header_without_check(CONTENT_LENGTH, length.as_str());
703 return_recycled_string(length);
704 }
705 let mut head_size: usize = self.get_reason_phrase().len() + B_16 + HTTP_BR.len();
706 head_size += self
707 .get_headers()
708 .iter()
709 .map(|header_entry: (&String, &VecDeque<String>)| {
710 let (header_key, header_values): (&String, &VecDeque<String>) = header_entry;
711 header_values
712 .iter()
713 .map(|header_value: &String| {
714 header_key.len() + COLON.len() + header_value.len() + HTTP_BR.len()
715 })
716 .sum::<usize>()
717 })
718 .sum::<usize>();
719 let mut response_string: String = String::with_capacity(head_size + body_len);
720 let _: fmt::Result = write!(
721 response_string,
722 "{} {} {}{HTTP_BR}",
723 self.get_version(),
724 self.get_status_code(),
725 self.get_reason_phrase()
726 );
727 self.get_headers()
728 .iter()
729 .for_each(|header_entry: (&String, &VecDeque<String>)| {
730 let (header_key, header_values): (&String, &VecDeque<String>) = header_entry;
731 for header_value in header_values.iter() {
732 Self::push_header(&mut response_string, header_key, header_value);
733 }
734 });
735 response_string.push_str(HTTP_BR);
736 let mut response_bytes: Vec<u8> = response_string.into_bytes();
737 match &compressed_body {
738 Some(body) => response_bytes.extend_from_slice(body),
739 None => response_bytes.extend_from_slice(self.get_body()),
740 }
741 response_bytes
742 }
743}