Skip to main content

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