Skip to main content

asknothingx2_util/api/
header_mut.rs

1use http::{
2    HeaderMap, HeaderName, HeaderValue,
3    header::{
4        ACCEPT, ACCEPT_ENCODING, ACCEPT_LANGUAGE, ACCESS_CONTROL_ALLOW_HEADERS,
5        ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN, AUTHORIZATION, CACHE_CONTROL,
6        CONNECTION, CONTENT_LENGTH, CONTENT_TYPE, ORIGIN, REFERER, USER_AGENT,
7    },
8};
9
10use crate::api::{
11    AuthScheme,
12    mime_type::{Application, Multipart, Text},
13};
14
15use super::{Error, error};
16
17pub mod headers {
18    use http::HeaderName;
19
20    pub const CLIENT_ID: HeaderName = HeaderName::from_static("client-id");
21    pub const X_API_KEY: HeaderName = HeaderName::from_static("x-api-key");
22    pub const X_REQUEST_ID: HeaderName = HeaderName::from_static("x-request-id");
23}
24
25pub struct HeaderMut<'a> {
26    header: &'a mut HeaderMap,
27}
28
29impl<'a> HeaderMut<'a> {
30    pub fn new(header: &'a mut HeaderMap) -> Self {
31        Self { header }
32    }
33
34    pub fn header(&mut self, key: HeaderName, value: HeaderValue) -> &mut Self {
35        self.header.insert(key, value);
36        self
37    }
38
39    pub fn header_static(&mut self, key: HeaderName, value: &'static str) -> &mut Self {
40        self.header.insert(key, HeaderValue::from_static(value));
41        self
42    }
43
44    pub fn header_static_sensitive(&mut self, key: HeaderName, value: &'static str) -> &mut Self {
45        let mut value = HeaderValue::from_static(value);
46        value.set_sensitive(true);
47        self.header.insert(key, value);
48        self
49    }
50
51    pub fn header_str(&mut self, key: HeaderName, value: &str) -> Result<&mut Self, Error> {
52        let val = HeaderValue::from_str(value).map_err(error::http::invalid_header)?;
53
54        self.header.insert(key, val);
55        Ok(self)
56    }
57
58    pub fn header_str_sensitive(
59        &mut self,
60        key: HeaderName,
61        value: &str,
62    ) -> Result<&mut Self, Error> {
63        let mut val = HeaderValue::from_str(value).map_err(error::http::invalid_header)?;
64        val.set_sensitive(true);
65
66        self.header.insert(key, val);
67        Ok(self)
68    }
69
70    pub fn append(&mut self, key: HeaderName, value: HeaderValue) -> &mut Self {
71        self.header.append(key, value);
72
73        self
74    }
75
76    pub fn extend(&mut self, headers: HeaderMap) -> &mut Self {
77        self.header.extend(headers);
78
79        self
80    }
81
82    pub fn is_empty(&self) -> bool {
83        self.header.is_empty()
84    }
85
86    /// Client-Id: id
87    pub fn client_id(&mut self, id: &str) -> Result<&mut Self, Error> {
88        self.header_str_sensitive(headers::CLIENT_ID, id)
89    }
90
91    /// User-Agent: agent
92    pub fn user_agent(&mut self, agent: &str) -> Result<&mut Self, Error> {
93        self.header_str(USER_AGENT, agent)
94    }
95
96    /// Cache-Control: no-cache
97    pub fn cache_control_no_cache(&mut self) -> &mut Self {
98        self.header
99            .insert(CACHE_CONTROL, HeaderValue::from_static("no-cache"));
100        self
101    }
102
103    /// Cache-Control: value
104    pub fn cache_control(&mut self, value: &str) -> Result<&mut Self, Error> {
105        self.header_str(CACHE_CONTROL, value)
106    }
107
108    /// X-API-Key: key
109    pub fn api_key(&mut self, key: &str) -> Result<&mut Self, Error> {
110        self.header_str(headers::X_API_KEY, key)
111    }
112
113    /// X-Request-ID: id
114    pub fn request_id(&mut self, id: &str) -> Result<&mut Self, Error> {
115        self.header_str(headers::X_REQUEST_ID, id)
116    }
117
118    /// Origin: origin
119    pub fn origin(&mut self, origin: &str) -> Result<&mut Self, Error> {
120        self.header_str(ORIGIN, origin)
121    }
122
123    /// Referer: referer
124    pub fn referer(&mut self, referer: &str) -> Result<&mut Self, Error> {
125        self.header_str(REFERER, referer)
126    }
127
128    // CORS headers
129    /// Access-Control-Allow-Origin: *
130    pub fn cors_allow_all(&mut self) -> &mut Self {
131        self.header
132            .insert(ACCESS_CONTROL_ALLOW_ORIGIN, HeaderValue::from_static("*"));
133        self
134    }
135
136    /// Access-Control-Allow-Origin: origin
137    pub fn cors_allow_origin(&mut self, origin: &str) -> Result<&mut Self, Error> {
138        self.header_str(ACCESS_CONTROL_ALLOW_ORIGIN, origin)
139    }
140
141    /// Access-Control-Allow-Methods: GET, POST, PUT, DELETE
142    pub fn cors_allow_methods_standard(&mut self) -> &mut Self {
143        self.header.insert(
144            ACCESS_CONTROL_ALLOW_METHODS,
145            HeaderValue::from_static("GET,POST,PUT,DELETE"),
146        );
147        self
148    }
149
150    /// Access-Control-Allow-Headers: Content-Type, Authorization
151    pub fn cors_allow_headers_standard(&mut self) -> &mut Self {
152        self.header.insert(
153            ACCESS_CONTROL_ALLOW_HEADERS,
154            HeaderValue::from_static("Content-Type,Authorization"),
155        );
156        self
157    }
158
159    /// Connection: keep-alive
160    pub fn connection_keep_alive(&mut self) -> &mut Self {
161        self.header
162            .insert(CONNECTION, HeaderValue::from_static("keep-alive"));
163        self
164    }
165
166    /// Connection: close
167    pub fn connection_close(&mut self) -> &mut Self {
168        self.header
169            .insert(CONNECTION, HeaderValue::from_static("close"));
170        self
171    }
172
173    /// Content-Length: length
174    pub fn content_length(&mut self, length: u64) -> &mut Self {
175        self.header.insert(
176            CONTENT_LENGTH,
177            HeaderValue::from_str(&length.to_string()).unwrap(),
178        );
179        self
180    }
181
182    /// Accept: application/json, Content-Type: application/json
183    pub fn json_api(&mut self) -> &mut Self {
184        self.accept_json().content_type_json()
185    }
186}
187
188impl<'a> HeaderMut<'a> {
189    /// ACCEPT: application/json
190    pub fn accept_json(&mut self) -> &mut Self {
191        self.header
192            .insert(ACCEPT, Application::Json.to_header_value());
193        self
194    }
195
196    /// ACCEPT: text/html
197    pub fn accept_html(&mut self) -> &mut Self {
198        self.header.insert(ACCEPT, Text::Html.to_header_value());
199        self
200    }
201
202    /// ACCEPT: text/plain
203    pub fn accept_text(&mut self) -> &mut Self {
204        self.header
205            .insert(ACCEPT, HeaderValue::from_static("text/plain"));
206        self
207    }
208
209    /// ACCEPT: */*
210    pub fn accept_any(&mut self) -> &mut Self {
211        self.header.insert(ACCEPT, HeaderValue::from_static("*/*"));
212        self
213    }
214
215    /// ACCEPT: multi items
216    pub fn accept_mulity(&mut self, items: &[&str]) -> Result<&mut Self, Error> {
217        self.header_str(ACCEPT, &items.join(","))
218    }
219
220    /// Accept-Encoding: gzip, deflate, br
221    pub fn accept_encoding_standard(&mut self) -> &mut Self {
222        self.header
223            .insert(ACCEPT_ENCODING, HeaderValue::from_static("gzip,deflate,br"));
224        self
225    }
226
227    /// Accept-Language: en-US, en;q=0.9
228    pub fn accept_language_en(&mut self) -> &mut Self {
229        self.header
230            .insert(ACCEPT_LANGUAGE, HeaderValue::from_static("en-US,en;q=0.9"));
231        self
232    }
233
234    /// Accept-Language: lang
235    pub fn accept_language(&mut self, lang: &str) -> Result<&mut Self, Error> {
236        self.header_str(ACCEPT_LANGUAGE, lang)
237    }
238}
239
240impl<'a> HeaderMut<'a> {
241    /// CONTENT-TYPE: application/x-www-form-urlencoded
242    pub fn content_type_formencoded(&mut self) -> &mut Self {
243        self.header
244            .insert(CONTENT_TYPE, Application::FormUrlEncoded.to_header_value());
245        self
246    }
247
248    /// CONTENT-TYPE: application/json
249    pub fn content_type_json(&mut self) -> &mut Self {
250        self.header
251            .insert(CONTENT_TYPE, Application::Json.to_header_value());
252        self
253    }
254
255    /// CONTENT-TYPE: text/plain
256    pub fn content_type_text(&mut self) -> &mut Self {
257        self.header
258            .insert(CONTENT_TYPE, Text::Plain.to_header_value());
259        self
260    }
261
262    /// CONTENT-TYPE: text/html
263    pub fn content_type_html(&mut self) -> &mut Self {
264        self.header
265            .insert(CONTENT_TYPE, Text::Html.to_header_value());
266        self
267    }
268
269    /// CONTENT-TYPE: multipart/form-data
270    pub fn content_type_multipart(&mut self) -> &mut Self {
271        self.header
272            .insert(CONTENT_TYPE, Multipart::FormData.to_header_value());
273        self
274    }
275}
276
277impl<'a> HeaderMut<'a> {
278    /// Authorization: type credentials
279    pub fn authorization(&mut self, auth: AuthScheme) -> &mut Self {
280        self.header
281            .insert(AUTHORIZATION, auth.to_header_value().unwrap());
282        self
283    }
284
285    pub fn basic_auth(&mut self, username: &str, password: &str) -> &mut Self {
286        self.authorization(AuthScheme::basic(username, password))
287    }
288
289    pub fn bearer_token(&mut self, token: &str) -> &mut Self {
290        self.authorization(AuthScheme::bearer(token))
291    }
292}