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
15 where
16 Self: Sized,
17 {
18 let split_lines: Vec<&[u8]> = split_multi_byte(response, HTTP_BR_BYTES);
19 let mut lines: IntoIter<&[u8]> = split_lines.into_iter();
20 let status_line: &[u8] = lines.next().unwrap_or(&[]);
21 let status_parts: Vec<&[u8]> = split_whitespace(&status_line);
22 let http_version: HttpVersion = status_parts
23 .get(0)
24 .and_then(|part: &&[u8]| from_utf8(part).ok())
25 .and_then(|version_str: &str| version_str.parse::<HttpVersion>().ok())
26 .unwrap_or_default();
27 let status_code: ResponseStatusCode = status_parts
28 .get(1)
29 .and_then(|part: &&[u8]| from_utf8(part).ok())
30 .and_then(|code_str: &str| code_str.parse().ok())
31 .unwrap_or(HttpStatus::Unknown.code());
32 let status_text: String = status_parts.get(2..).map_or_else(
33 || HttpStatus::Unknown.to_string(),
34 |parts: &[&[u8]]| {
35 if parts.is_empty() {
36 HttpStatus::Unknown.to_string()
37 } else if parts.len() == 1 {
38 String::from_utf8_lossy(parts[0]).into_owned()
39 } else {
40 let total_len: usize =
41 parts.iter().map(|p: &&[u8]| p.len()).sum::<usize>() + parts.len() - 1;
42 let mut result: String = String::with_capacity(total_len);
43 for (i, part) in parts.iter().enumerate() {
44 if i > 0 {
45 result.push(' ');
46 }
47 result.push_str(&String::from_utf8_lossy(part));
48 }
49 result
50 }
51 },
52 );
53 let mut headers: HashMapXxHash3_64<String, VecDeque<String>> = hash_map_xx_hash3_64();
54 for line in lines.by_ref() {
55 if line.is_empty() {
56 break;
57 }
58 let mut colon_pos: Option<usize> = None;
59 for (i, &byte) in line.iter().enumerate() {
60 if byte == b':' {
61 colon_pos = Some(i);
62 break;
63 }
64 }
65 if let Some(pos) = colon_pos {
66 if pos > 0 && pos + 1 < line.len() {
67 let key_bytes: &[u8] = &line[..pos];
68 let value_start: usize = if line.get(pos + 1) == Some(&b' ') {
69 pos + 2
70 } else {
71 pos + 1
72 };
73 let value_bytes: &[u8] = &line[value_start..];
74 if let (Ok(key_str), Ok(value_str)) =
75 (from_utf8(key_bytes), from_utf8(value_bytes))
76 {
77 let mut value_deque: VecDeque<String> = VecDeque::new();
78 value_deque.push_front(value_str.trim().to_string());
79 headers.insert(key_str.trim().to_string(), value_deque);
80 }
81 }
82 }
83 }
84 let body: Vec<u8> = match lines.len() {
85 0 => Vec::new(),
86 1 => {
87 let line: &[u8] = lines.next().unwrap_or(&[]);
88 let mut body = Vec::with_capacity(line.len());
89 body.extend_from_slice(line);
90 body
91 }
92 _ => {
93 let lines_slice: &[&[u8]] = lines.as_slice();
94 let total_size: usize = lines_slice
95 .iter()
96 .map(|line: &&[u8]| line.len())
97 .sum::<usize>()
98 + lines_slice.len().saturating_sub(1) * BR_BYTES.len();
99 let mut body: Vec<u8> = Vec::with_capacity(total_size);
100 let mut first: bool = true;
101 for line in lines {
102 if !first {
103 body.extend_from_slice(BR_BYTES);
104 }
105 body.extend_from_slice(line);
106 first = false;
107 }
108 body
109 }
110 };
111 HttpResponseBinary {
112 http_version: Arc::new(RwLock::new(http_version)),
113 status_code,
114 status_text: Arc::new(RwLock::new(status_text)),
115 headers: Arc::new(RwLock::new(headers)),
116 body: Arc::new(RwLock::new(body)),
117 }
118 }
119
120 fn binary(&self) -> Self::OutputBinary {
121 self.clone()
122 }
123
124 fn text(&self) -> HttpResponseText {
125 let body: String = self.body.read().map_or(String::new(), |body_ref| {
126 String::from_utf8_lossy(&body_ref).into_owned()
127 });
128 HttpResponseText {
129 http_version: Arc::clone(&self.http_version),
130 status_code: self.status_code,
131 status_text: Arc::clone(&self.status_text),
132 headers: Arc::clone(&self.headers),
133 body: Arc::new(RwLock::new(body)),
134 }
135 }
136
137 fn decode(&self, buffer_size: usize) -> HttpResponseBinary {
138 let decoded_body: Vec<u8> = {
139 let headers_guard = self.headers.read();
140 let body_guard = self.body.read();
141 match (headers_guard, body_guard) {
142 (Ok(headers_ref), Ok(body_ref)) => {
143 let mut string_headers: HashMapXxHash3_64<String, String> =
144 hash_map_xx_hash3_64();
145 for (key, value_deque) in headers_ref.iter() {
146 if let Some(first_value) = value_deque.front() {
147 string_headers.insert(key.clone(), first_value.clone());
148 }
149 }
150 Compress::from(&string_headers)
151 .decode(&*body_ref, buffer_size)
152 .into_owned()
153 }
154 _ => Vec::new(),
155 }
156 };
157 HttpResponseBinary {
158 http_version: Arc::clone(&self.http_version),
159 status_code: self.status_code,
160 status_text: Arc::clone(&self.status_text),
161 headers: Arc::clone(&self.headers),
162 body: Arc::new(RwLock::new(decoded_body)),
163 }
164 }
165}
166
167impl HttpResponseBinary {
168 pub fn get_http_version(&self) -> HttpVersion {
173 if let Ok(http_version) = self.http_version.read() {
174 return http_version
175 .to_string()
176 .parse::<HttpVersion>()
177 .unwrap_or_default();
178 }
179 return HttpVersion::default();
180 }
181
182 pub fn get_status_code(&self) -> ResponseStatusCode {
187 self.status_code
188 }
189
190 pub fn get_status_text(&self) -> String {
195 if let Ok(status_text) = self.status_text.read() {
196 return status_text.to_string();
197 }
198 return HttpStatus::default().to_string();
199 }
200
201 pub fn get_headers(&self) -> ResponseHeaders {
206 if let Ok(headers) = self.headers.read() {
207 return headers.clone();
208 }
209 return hash_map_xx_hash3_64();
210 }
211
212 pub fn get_body(&self) -> RequestBody {
217 if let Ok(body) = self.body.read() {
218 return body.clone();
219 }
220 return RequestBody::new();
221 }
222}
223
224impl Default for HttpResponseBinary {
225 fn default() -> Self {
226 Self {
227 http_version: Arc::new(RwLock::new(HttpVersion::Unknown(String::new()))),
228 status_code: HttpStatus::Unknown.code(),
229 status_text: Arc::new(RwLock::new(HttpStatus::Unknown.to_string())),
230 headers: Arc::new(RwLock::new(hash_map_xx_hash3_64())),
231 body: Arc::new(RwLock::new(Vec::new())),
232 }
233 }
234}