http_request/response/response_binary/
impl.rs1use crate::*;
2
3impl ResponseTrait for HttpResponseBinary {
12 type OutputText = HttpResponseText;
13 type OutputBinary = HttpResponseBinary;
14 fn from(response: &[u8]) -> Self
24 where
25 Self: Sized,
26 {
27 let split_lines: Vec<&[u8]> = split_multi_byte(response, HTTP_BR_BYTES);
28 let mut lines: IntoIter<&[u8]> = split_lines.into_iter();
29 let status_line: &[u8] = lines.next().unwrap_or(&[]);
30 let status_parts: Vec<&[u8]> = split_whitespace(status_line);
31 let http_version: HttpVersion = status_parts
32 .first()
33 .and_then(|part: &&[u8]| from_utf8(part).ok())
34 .and_then(|version_str: &str| version_str.parse::<HttpVersion>().ok())
35 .unwrap_or_default();
36 let status_code: ResponseStatusCode = status_parts
37 .get(1)
38 .and_then(|part: &&[u8]| from_utf8(part).ok())
39 .and_then(|code_str: &str| code_str.parse().ok())
40 .unwrap_or(HttpStatus::Unknown.code());
41 let status_text: String = status_parts.get(2..).map_or_else(
42 || HttpStatus::Unknown.to_string(),
43 |parts: &[&[u8]]| {
44 if parts.is_empty() {
45 HttpStatus::Unknown.to_string()
46 } else if parts.len() == 1 {
47 String::from_utf8_lossy(parts[0]).into_owned()
48 } else {
49 let total_len: usize =
50 parts.iter().map(|p: &&[u8]| p.len()).sum::<usize>() + parts.len() - 1;
51 let mut result: String = String::with_capacity(total_len);
52 for (i, part) in parts.iter().enumerate() {
53 if i > 0 {
54 result.push(' ');
55 }
56 result.push_str(&String::from_utf8_lossy(part));
57 }
58 result
59 }
60 },
61 );
62 let mut headers: HashMapXxHash3_64<String, VecDeque<String>> = hash_map_xx_hash3_64();
63 for line in lines.by_ref() {
64 if line.is_empty() {
65 break;
66 }
67 let mut colon_pos: Option<usize> = None;
68 for (i, &byte) in line.iter().enumerate() {
69 if byte == COLON_U8 {
70 colon_pos = Some(i);
71 break;
72 }
73 }
74 if let Some(pos) = colon_pos
75 && pos > 0
76 && pos + 1 < line.len()
77 {
78 let key_bytes: &[u8] = &line[..pos];
79 let value_start: usize = if line.get(pos + 1) == Some(&SPACE_U8) {
80 pos + 2
81 } else {
82 pos + 1
83 };
84 let value_bytes: &[u8] = &line[value_start..];
85 if let (Ok(key_str), Ok(value_str)) = (from_utf8(key_bytes), from_utf8(value_bytes))
86 {
87 let mut value_deque: VecDeque<String> = VecDeque::new();
88 value_deque.push_front(value_str.trim().to_string());
89 headers.insert(key_str.trim().to_string(), value_deque);
90 }
91 }
92 }
93 let body: Vec<u8> = match lines.len() {
94 0 => Vec::new(),
95 1 => {
96 let line: &[u8] = lines.next().unwrap_or(&[]);
97 let mut body = Vec::with_capacity(line.len());
98 body.extend_from_slice(line);
99 body
100 }
101 _ => {
102 let lines_slice: &[&[u8]] = lines.as_slice();
103 let total_size: usize = lines_slice
104 .iter()
105 .map(|line: &&[u8]| line.len())
106 .sum::<usize>()
107 + lines_slice.len().saturating_sub(1) * BR_BYTES.len();
108 let mut body: Vec<u8> = Vec::with_capacity(total_size);
109 let mut first: bool = true;
110 for line in lines {
111 if !first {
112 body.extend_from_slice(BR_BYTES);
113 }
114 body.extend_from_slice(line);
115 first = false;
116 }
117 body
118 }
119 };
120 HttpResponseBinary {
121 http_version: Arc::new(RwLock::new(http_version)),
122 status_code,
123 status_text: Arc::new(RwLock::new(status_text)),
124 headers: Arc::new(RwLock::new(headers)),
125 body: Arc::new(RwLock::new(body)),
126 }
127 }
128
129 fn binary(&self) -> Self::OutputBinary {
135 self.clone()
136 }
137
138 fn text(&self) -> HttpResponseText {
144 let body: String = self.body.read().map_or(String::new(), |body_ref| {
145 String::from_utf8_lossy(&body_ref).into_owned()
146 });
147 HttpResponseText {
148 http_version: Arc::clone(&self.http_version),
149 status_code: self.status_code,
150 status_text: Arc::clone(&self.status_text),
151 headers: Arc::clone(&self.headers),
152 body: Arc::new(RwLock::new(body)),
153 }
154 }
155
156 fn decode(&self, buffer_size: usize) -> HttpResponseBinary {
166 let decoded_body: Vec<u8> = {
167 let headers_guard = self.headers.read();
168 let body_guard = self.body.read();
169 match (headers_guard, body_guard) {
170 (Ok(headers_ref), Ok(body_ref)) => {
171 let mut string_headers: HashMapXxHash3_64<String, String> =
172 hash_map_xx_hash3_64();
173 for (key, value_deque) in headers_ref.iter() {
174 if let Some(first_value) = value_deque.front() {
175 string_headers.insert(key.clone(), first_value.clone());
176 }
177 }
178 Compress::from(&string_headers)
179 .decode(&body_ref, buffer_size)
180 .into_owned()
181 }
182 _ => Vec::new(),
183 }
184 };
185 HttpResponseBinary {
186 http_version: Arc::clone(&self.http_version),
187 status_code: self.status_code,
188 status_text: Arc::clone(&self.status_text),
189 headers: Arc::clone(&self.headers),
190 body: Arc::new(RwLock::new(decoded_body)),
191 }
192 }
193}
194
195impl HttpResponseBinary {
196 pub fn get_http_version(&self) -> HttpVersion {
207 if let Ok(http_version) = self.http_version.read() {
208 return http_version
209 .to_string()
210 .parse::<HttpVersion>()
211 .unwrap_or_default();
212 }
213 HttpVersion::default()
214 }
215
216 pub fn get_status_code(&self) -> ResponseStatusCode {
227 self.status_code
228 }
229
230 pub fn get_status_text(&self) -> String {
241 if let Ok(status_text) = self.status_text.read() {
242 return status_text.to_string();
243 }
244 HttpStatus::default().to_string()
245 }
246
247 pub fn get_headers(&self) -> ResponseHeaders {
258 if let Ok(headers) = self.headers.read() {
259 return headers.clone();
260 }
261 hash_map_xx_hash3_64()
262 }
263
264 pub fn get_body(&self) -> RequestBody {
275 if let Ok(body) = self.body.read() {
276 return body.clone();
277 }
278 RequestBody::new()
279 }
280}
281
282impl Default for HttpResponseBinary {
288 fn default() -> Self {
289 Self {
290 http_version: Arc::new(RwLock::new(HttpVersion::Unknown(String::new()))),
291 status_code: HttpStatus::Unknown.code(),
292 status_text: Arc::new(RwLock::new(HttpStatus::Unknown.to_string())),
293 headers: Arc::new(RwLock::new(hash_map_xx_hash3_64())),
294 body: Arc::new(RwLock::new(Vec::new())),
295 }
296 }
297}