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 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}