http_request/response/response_binary/
impl.rs1use super::r#type::HttpResponseBinary;
2use crate::{
3 response::{r#trait::ResponseTrait, response_text::r#type::HttpResponseText},
4 utils::vec::{split_multi_byte, split_whitespace},
5};
6use http_compress::Compress;
7use http_type::*;
8use std::{
9 collections::HashMap,
10 sync::{Arc, RwLock},
11 vec::IntoIter,
12};
13
14impl ResponseTrait for HttpResponseBinary {
23 type OutputText = HttpResponseText;
24 type OutputBinary = HttpResponseBinary;
25
26 #[inline]
27 fn from(response: &[u8]) -> Self
28 where
29 Self: Sized,
30 {
31 let split_lines: Vec<&[u8]> = split_multi_byte(response, HTTP_BR_BYTES);
32 let mut lines: IntoIter<&[u8]> = split_lines.into_iter();
33 let status_line: &[u8] = lines.next().unwrap_or(&[]);
34 let status_parts: Vec<&[u8]> = split_whitespace(&status_line);
35 let http_version: HttpVersion = String::from_utf8_lossy(
36 status_parts
37 .get(0)
38 .unwrap_or(&HttpVersion::Unknown(String::new()).to_string().as_bytes()),
39 )
40 .to_string()
41 .parse::<HttpVersion>()
42 .unwrap_or_default();
43 let status_code: StatusCodeUsize = status_parts
44 .get(1)
45 .and_then(|part| std::str::from_utf8(part).ok())
46 .unwrap_or(&StatusCode::Ok.to_string())
47 .parse()
48 .unwrap_or(StatusCode::Unknown.code());
49 let status_text: String = status_parts.get(2..).map_or_else(
50 || StatusCode::Unknown.to_string(),
51 |parts| String::from_utf8_lossy(&parts.concat()).to_string(),
52 );
53 let mut headers: HashMap<String, String> = HashMap::new();
54 while let Some(line) = lines.next() {
55 if line.is_empty() {
56 break;
57 }
58 let header_parts: Vec<&[u8]> = split_multi_byte(&line, COLON_SPACE_BYTES);
59 if header_parts.len() == 2 {
60 let key: String = String::from_utf8_lossy(header_parts[0]).trim().to_string();
61 let value: String = String::from_utf8_lossy(header_parts[1]).trim().to_string();
62 headers.insert(key, value);
63 }
64 }
65 let body: Vec<u8> = lines.clone().collect::<Vec<&[u8]>>().join(BR_BYTES);
66 HttpResponseBinary {
67 http_version: Arc::new(RwLock::new(http_version)),
68 status_code,
69 status_text: Arc::new(RwLock::new(status_text)),
70 headers: Arc::new(RwLock::new(headers)),
71 body: Arc::new(RwLock::new(body)),
72 }
73 }
74
75 #[inline]
76 fn binary(&self) -> Self::OutputBinary {
77 self.clone()
78 }
79
80 #[inline]
81 fn text(&self) -> HttpResponseText {
82 let http_response: HttpResponseBinary = self.clone();
83 let body_bin: Vec<u8> = http_response
84 .body
85 .read()
86 .map_or(Vec::new(), |body| body.clone());
87 let body: String = String::from_utf8_lossy(&body_bin).to_string();
88 HttpResponseText {
89 http_version: http_response.http_version,
90 status_code: http_response.status_code,
91 status_text: http_response.status_text,
92 headers: http_response.headers,
93 body: Arc::new(RwLock::new(body)),
94 }
95 }
96
97 #[inline]
98 fn decode(&self, buffer_size: usize) -> HttpResponseBinary {
99 let http_response: HttpResponseBinary = self.clone();
100 let body: Vec<u8> = Compress::from(
101 &self
102 .headers
103 .read()
104 .map_or(HashMap::new(), |headers| headers.clone()),
105 )
106 .decode(
107 &self.body.read().map_or(Vec::new(), |body| body.clone()),
108 buffer_size,
109 )
110 .into_owned();
111 HttpResponseBinary {
112 http_version: http_response.http_version,
113 status_code: http_response.status_code,
114 status_text: http_response.status_text,
115 headers: http_response.headers,
116 body: Arc::new(RwLock::new(body)),
117 }
118 }
119}
120
121impl HttpResponseBinary {
122 #[inline]
127 pub fn get_http_version(&self) -> HttpVersion {
128 if let Ok(http_version) = self.http_version.read() {
129 return http_version
130 .to_string()
131 .parse::<HttpVersion>()
132 .unwrap_or_default();
133 }
134 return HttpVersion::default();
135 }
136
137 #[inline]
142 pub fn get_status_code(&self) -> StatusCodeUsize {
143 self.status_code
144 }
145
146 #[inline]
151 pub fn get_status_text(&self) -> String {
152 if let Ok(status_text) = self.status_text.read() {
153 return status_text.to_string();
154 }
155 return StatusCode::default().to_string();
156 }
157
158 #[inline]
163 pub fn get_headers(&self) -> HttpHeaderMap {
164 if let Ok(headers) = self.headers.read() {
165 return headers.clone();
166 }
167 return HttpHeaderMap::new();
168 }
169
170 #[inline]
175 pub fn get_body(&self) -> HttpBodyVec {
176 if let Ok(body) = self.body.read() {
177 return body.clone();
178 }
179 return HttpBodyVec::new();
180 }
181}
182
183impl Default for HttpResponseBinary {
184 #[inline]
185 fn default() -> Self {
186 Self {
187 http_version: Arc::new(RwLock::new(HttpVersion::Unknown(String::new()))),
188 status_code: StatusCode::Unknown.code(),
189 status_text: Arc::new(RwLock::new(StatusCode::Unknown.to_string())),
190 headers: Arc::new(RwLock::new(HashMap::new())),
191 body: Arc::new(RwLock::new(Vec::new())),
192 }
193 }
194}