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