Skip to main content

http_type/response/
impl.rs

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