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 .get(0)
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 == b':' {
70 colon_pos = Some(i);
71 break;
72 }
73 }
74 if let Some(pos) = colon_pos {
75 if pos > 0 && pos + 1 < line.len() {
76 let key_bytes: &[u8] = &line[..pos];
77 let value_start: usize = if line.get(pos + 1) == Some(&b' ') {
78 pos + 2
79 } else {
80 pos + 1
81 };
82 let value_bytes: &[u8] = &line[value_start..];
83 if let (Ok(key_str), Ok(value_str)) =
84 (from_utf8(key_bytes), from_utf8(value_bytes))
85 {
86 let mut value_deque: VecDeque<String> = VecDeque::new();
87 value_deque.push_front(value_str.trim().to_string());
88 headers.insert(key_str.trim().to_string(), value_deque);
89 }
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 {
206 if let Ok(http_version) = self.http_version.read() {
207 return http_version
208 .to_string()
209 .parse::<HttpVersion>()
210 .unwrap_or_default();
211 }
212 return HttpVersion::default();
213 }
214
215 pub fn get_status_code(&self) -> ResponseStatusCode {
225 self.status_code
226 }
227
228 pub fn get_status_text(&self) -> String {
238 if let Ok(status_text) = self.status_text.read() {
239 return status_text.to_string();
240 }
241 return HttpStatus::default().to_string();
242 }
243
244 pub fn get_headers(&self) -> ResponseHeaders {
254 if let Ok(headers) = self.headers.read() {
255 return headers.clone();
256 }
257 return hash_map_xx_hash3_64();
258 }
259
260 pub fn get_body(&self) -> RequestBody {
270 if let Ok(body) = self.body.read() {
271 return body.clone();
272 }
273 return RequestBody::new();
274 }
275}
276
277impl Default for HttpResponseBinary {
283 fn default() -> Self {
284 Self {
285 http_version: Arc::new(RwLock::new(HttpVersion::Unknown(String::new()))),
286 status_code: HttpStatus::Unknown.code(),
287 status_text: Arc::new(RwLock::new(HttpStatus::Unknown.to_string())),
288 headers: Arc::new(RwLock::new(hash_map_xx_hash3_64())),
289 body: Arc::new(RwLock::new(Vec::new())),
290 }
291 }
292}