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, 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 headers.insert(key_str.trim().to_string(), value_str.trim().to_string());
78 }
79 }
80 }
81 }
82 let body: Vec<u8> = match lines.len() {
83 0 => Vec::new(),
84 1 => {
85 let line: &[u8] = lines.next().unwrap_or(&[]);
86 let mut body = Vec::with_capacity(line.len());
87 body.extend_from_slice(line);
88 body
89 }
90 _ => {
91 let lines_slice: &[&[u8]] = lines.as_slice();
92 let total_size: usize = lines_slice
93 .iter()
94 .map(|line: &&[u8]| line.len())
95 .sum::<usize>()
96 + lines_slice.len().saturating_sub(1) * BR_BYTES.len();
97 let mut body: Vec<u8> = Vec::with_capacity(total_size);
98 let mut first: bool = true;
99 for line in lines {
100 if !first {
101 body.extend_from_slice(BR_BYTES);
102 }
103 body.extend_from_slice(line);
104 first = false;
105 }
106 body
107 }
108 };
109 HttpResponseBinary {
110 http_version: Arc::new(RwLock::new(http_version)),
111 status_code,
112 status_text: Arc::new(RwLock::new(status_text)),
113 headers: Arc::new(RwLock::new(headers)),
114 body: Arc::new(RwLock::new(body)),
115 }
116 }
117
118 fn binary(&self) -> Self::OutputBinary {
119 self.clone()
120 }
121
122 fn text(&self) -> HttpResponseText {
123 let body: String = self.body.read().map_or(String::new(), |body_ref| {
124 String::from_utf8_lossy(&body_ref).into_owned()
125 });
126 HttpResponseText {
127 http_version: Arc::clone(&self.http_version),
128 status_code: self.status_code,
129 status_text: Arc::clone(&self.status_text),
130 headers: Arc::clone(&self.headers),
131 body: Arc::new(RwLock::new(body)),
132 }
133 }
134
135 fn decode(&self, buffer_size: usize) -> HttpResponseBinary {
136 let decoded_body: Vec<u8> = {
137 let headers_guard = self.headers.read();
138 let body_guard = self.body.read();
139 match (headers_guard, body_guard) {
140 (Ok(headers_ref), Ok(body_ref)) => Compress::from(&*headers_ref)
141 .decode(&*body_ref, buffer_size)
142 .into_owned(),
143 _ => Vec::new(),
144 }
145 };
146 HttpResponseBinary {
147 http_version: Arc::clone(&self.http_version),
148 status_code: self.status_code,
149 status_text: Arc::clone(&self.status_text),
150 headers: Arc::clone(&self.headers),
151 body: Arc::new(RwLock::new(decoded_body)),
152 }
153 }
154}
155
156impl HttpResponseBinary {
157 pub fn get_http_version(&self) -> HttpVersion {
162 if let Ok(http_version) = self.http_version.read() {
163 return http_version
164 .to_string()
165 .parse::<HttpVersion>()
166 .unwrap_or_default();
167 }
168 return HttpVersion::default();
169 }
170
171 pub fn get_status_code(&self) -> ResponseStatusCode {
176 self.status_code
177 }
178
179 pub fn get_status_text(&self) -> String {
184 if let Ok(status_text) = self.status_text.read() {
185 return status_text.to_string();
186 }
187 return HttpStatus::default().to_string();
188 }
189
190 pub fn get_headers(&self) -> ResponseHeaders {
195 if let Ok(headers) = self.headers.read() {
196 return headers.clone();
197 }
198 return hash_map_xx_hash3_64();
199 }
200
201 pub fn get_body(&self) -> RequestBody {
206 if let Ok(body) = self.body.read() {
207 return body.clone();
208 }
209 return RequestBody::new();
210 }
211}
212
213impl Default for HttpResponseBinary {
214 fn default() -> Self {
215 Self {
216 http_version: Arc::new(RwLock::new(HttpVersion::Unknown(String::new()))),
217 status_code: HttpStatus::Unknown.code(),
218 status_text: Arc::new(RwLock::new(HttpStatus::Unknown.to_string())),
219 headers: Arc::new(RwLock::new(hash_map_xx_hash3_64())),
220 body: Arc::new(RwLock::new(Vec::new())),
221 }
222 }
223}