http_request/response/response_text/
impl.rs

1use crate::*;
2
3/// Implements the `ResponseTrait` trait for `HttpResponseText`.
4///
5/// This implementation allows `HttpResponseText` to convert between text and binary
6/// representations of HTTP responses. It provides methods for parsing raw responses, as well
7/// as accessing text and binary formats.
8///
9/// # Associated Types
10/// - `OutputText`: Specifies the text representation of an HTTP response (`HttpResponseText`).
11/// - `OutputBinary`: Specifies the binary representation of an HTTP response (`HttpResponseBinary`).
12impl ResponseTrait for HttpResponseText {
13    type OutputText = HttpResponseText;
14    type OutputBinary = HttpResponseBinary;
15
16    fn from(response: &[u8]) -> Self::OutputText
17    where
18        Self: Sized,
19    {
20        <HttpResponseBinary as ResponseTrait>::from(response).text()
21    }
22
23    fn text(&self) -> Self::OutputText {
24        self.clone()
25    }
26
27    fn binary(&self) -> HttpResponseBinary {
28        let body: Vec<u8> = self
29            .body
30            .read()
31            .map_or(Vec::new(), |body| body.clone().into_bytes());
32        HttpResponseBinary {
33            http_version: self.http_version.clone(),
34            status_code: self.status_code,
35            status_text: self.status_text.clone(),
36            headers: self.headers.clone(),
37            body: Arc::new(RwLock::new(body)),
38        }
39    }
40
41    fn decode(&self, buffer_size: usize) -> HttpResponseBinary {
42        let http_response: HttpResponseText = self.clone();
43        let tmp_body: Vec<u8> = self
44            .body
45            .read()
46            .map_or(Vec::new(), |body| body.as_bytes().to_vec())
47            .to_vec();
48        let headers: HashMapXxHash3_64<String, String> =
49            self.headers
50                .read()
51                .map_or(hash_map_xx_hash3_64(), |headers_ref| {
52                    let mut string_headers: HashMapXxHash3_64<String, String> =
53                        hash_map_xx_hash3_64();
54                    for (key, value_deque) in headers_ref.iter() {
55                        if let Some(first_value) = value_deque.front() {
56                            string_headers.insert(key.clone(), first_value.clone());
57                        }
58                    }
59                    string_headers
60                });
61        let body: Vec<u8> = Compress::from(&headers)
62            .decode(&tmp_body, buffer_size)
63            .into_owned();
64        HttpResponseBinary {
65            http_version: http_response.http_version,
66            status_code: http_response.status_code,
67            status_text: http_response.status_text,
68            headers: http_response.headers,
69            body: Arc::new(RwLock::new(body)),
70        }
71    }
72}
73
74impl HttpResponseText {
75    /// Retrieves the HTTP version associated with this response.
76    ///
77    /// # Returns
78    /// - `HttpVersion`: The HTTP version (e.g., HTTP/1.1, HTTP/2, etc.) used for the response.
79    pub fn get_http_version(&self) -> HttpVersion {
80        if let Ok(http_version) = self.http_version.read() {
81            return http_version
82                .to_string()
83                .parse::<HttpVersion>()
84                .unwrap_or_default();
85        }
86        return HttpVersion::default();
87    }
88
89    /// Retrieves the HTTP status code associated with this response.
90    ///
91    /// # Returns
92    /// - `ResponseStatusCode`: The HTTP status code as a usize (e.g., 200 for OK, 404 for Not Found).
93    pub fn get_status_code(&self) -> ResponseStatusCode {
94        self.status_code
95    }
96
97    /// Retrieves the status text associated with the HTTP status code.
98    ///
99    /// # Returns
100    /// - `String`: The human-readable status text (e.g., "OK" for status code 200, "Not Found" for status code 404).
101    pub fn get_status_text(&self) -> String {
102        if let Ok(status_text) = self.status_text.read() {
103            return status_text.to_string();
104        }
105        return HttpStatus::default().to_string();
106    }
107
108    /// Retrieves the headers of the HTTP response.
109    ///
110    /// # Returns
111    /// - `ResponseHeaders`: A map of header names and their corresponding values as key-value pairs.
112    pub fn get_headers(&self) -> ResponseHeaders {
113        if let Ok(headers) = self.headers.read() {
114            return headers.clone();
115        }
116        return hash_map_xx_hash3_64();
117    }
118
119    /// Retrieves the body content of the HTTP response as a `String`.
120    ///
121    /// This method attempts to read the body of the response. If the body can be successfully read,
122    /// it is converted into a `String` and returned. If reading the body fails, an empty string is returned.
123    ///
124    /// # Returns
125    /// - `RequestBodyString`: The body of the response as a string. If the body could not be read,
126    ///   an empty string is returned.
127    pub fn get_body(&self) -> RequestBodyString {
128        if let Ok(body) = self.body.read() {
129            return body.to_string();
130        }
131        return RequestBodyString::new();
132    }
133}
134
135impl Default for HttpResponseText {
136    fn default() -> Self {
137        Self {
138            http_version: Arc::new(RwLock::new(HttpVersion::Unknown(String::new()))),
139            status_code: HttpStatus::Unknown.code(),
140            status_text: Arc::new(RwLock::new(HttpStatus::Unknown.to_string())),
141            headers: Arc::new(RwLock::new(hash_map_xx_hash3_64())),
142            body: Arc::new(RwLock::new(String::new())),
143        }
144    }
145}