1use crate::cookie::CookieJar;
7use http::HeaderMap;
8
9pub fn chrome_142_headers() -> Vec<(&'static str, &'static str)> {
11 vec![
12 ("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36"),
13 ("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"),
14 ("Accept-Language", "en-US,en;q=0.9"),
15 ("Accept-Encoding", "gzip, deflate, br, zstd"),
16 ("Sec-Fetch-Dest", "document"),
17 ("Sec-Fetch-Mode", "navigate"),
18 ("Sec-Fetch-Site", "none"),
19 ("Sec-Fetch-User", "?1"),
20 ("Sec-Ch-Ua", r#""Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="24""#),
21 ("Sec-Ch-Ua-Mobile", "?0"),
22 ("Sec-Ch-Ua-Platform", r#""macOS""#),
23 ("Sec-Ch-Ua-Arch", r#""arm64""#),
24 ("Sec-Ch-Ua-Bitness", r#""64""#),
25 ("Sec-Ch-Ua-Full-Version-List", r#""Chromium";v="142.0.6367.118", "Google Chrome";v="142.0.6367.118", "Not_A Brand";v="24.0.0.0""#),
26 ("Sec-Ch-Ua-Model", r#""""#),
27 ("Sec-Ch-Ua-Platform-Version", r#""15.5.0""#),
28 ("Sec-Ch-Ua-Wow64", "?0"),
29 ("Upgrade-Insecure-Requests", "1"),
30 ("Connection", "keep-alive"),
31 ]
32}
33
34pub fn chrome_142_ajax_headers() -> Vec<(&'static str, &'static str)> {
38 vec![
39 ("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36"),
40 ("Accept", "application/json, text/plain, */*"),
41 ("Accept-Language", "en-US,en;q=0.9"),
42 ("Accept-Encoding", "gzip, deflate, br, zstd"),
43 ("Content-Type", "application/json"),
44 ("Sec-Fetch-Dest", "empty"),
45 ("Sec-Fetch-Mode", "cors"),
46 ("Sec-Fetch-Site", "same-origin"),
47 ("Sec-Ch-Ua", r#""Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="24""#),
48 ("Sec-Ch-Ua-Mobile", "?0"),
49 ("Sec-Ch-Ua-Platform", r#""macOS""#),
50 ("Connection", "keep-alive"),
51 ]
52}
53
54pub fn chrome_142_form_headers() -> Vec<(&'static str, &'static str)> {
56 vec![
57 ("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36"),
58 ("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"),
59 ("Accept-Language", "en-US,en;q=0.9"),
60 ("Accept-Encoding", "gzip, deflate, br, zstd"),
61 ("Content-Type", "application/x-www-form-urlencoded"),
62 ("Sec-Fetch-Dest", "document"),
63 ("Sec-Fetch-Mode", "navigate"),
64 ("Sec-Fetch-Site", "same-origin"),
65 ("Sec-Ch-Ua", r#""Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="24""#),
66 ("Sec-Ch-Ua-Mobile", "?0"),
67 ("Sec-Ch-Ua-Platform", r#""macOS""#),
68 ("Sec-Ch-Ua-Arch", r#""arm64""#),
69 ("Sec-Ch-Ua-Bitness", r#""64""#),
70 ("Sec-Ch-Ua-Full-Version-List", r#""Chromium";v="142.0.6367.118", "Google Chrome";v="142.0.6367.118", "Not_A Brand";v="24.0.0.0""#),
71 ("Sec-Ch-Ua-Model", r#""""#),
72 ("Sec-Ch-Ua-Platform-Version", r#""15.5.0""#),
73 ("Sec-Ch-Ua-Wow64", "?0"),
74 ("Upgrade-Insecure-Requests", "1"),
75 ("Connection", "keep-alive"),
76 ]
77}
78
79pub fn chrome_143_headers() -> Vec<(&'static str, &'static str)> {
81 vec![
82 ("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36"),
83 ("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"),
84 ("Accept-Language", "en-US,en;q=0.9"),
85 ("Accept-Encoding", "gzip, deflate, br, zstd"),
86 ("Sec-Fetch-Dest", "document"),
87 ("Sec-Fetch-Mode", "navigate"),
88 ("Sec-Fetch-Site", "none"),
89 ("Sec-Fetch-User", "?1"),
90 ("Sec-Ch-Ua", r#""Google Chrome";v="143", "Chromium";v="143", "Not A(Brand";v="99""#),
91 ("Sec-Ch-Ua-Mobile", "?0"),
92 ("Sec-Ch-Ua-Platform", r#""macOS""#),
93 ("Sec-Ch-Ua-Arch", r#""arm64""#),
94 ("Sec-Ch-Ua-Bitness", r#""64""#),
95 ("Sec-Ch-Ua-Full-Version-List", r#""Google Chrome";v="143.0.7499.40", "Chromium";v="143.0.7499.40", "Not A(Brand";v="99.0.0.0""#),
96 ("Sec-Ch-Ua-Model", r#""""#),
97 ("Sec-Ch-Ua-Platform-Version", r#""15.5.0""#),
98 ("Sec-Ch-Ua-Wow64", "?0"),
99 ("Upgrade-Insecure-Requests", "1"),
100 ("Connection", "keep-alive"),
101 ]
102}
103
104pub fn chrome_143_ajax_headers() -> Vec<(&'static str, &'static str)> {
106 vec![
107 ("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36"),
108 ("Accept", "application/json, text/plain, */*"),
109 ("Accept-Language", "en-US,en;q=0.9"),
110 ("Accept-Encoding", "gzip, deflate, br, zstd"),
111 ("Content-Type", "application/json"),
112 ("Sec-Fetch-Dest", "empty"),
113 ("Sec-Fetch-Mode", "cors"),
114 ("Sec-Fetch-Site", "same-origin"),
115 ("Sec-Ch-Ua", r#""Google Chrome";v="143", "Chromium";v="143", "Not A(Brand";v="99""#),
116 ("Sec-Ch-Ua-Mobile", "?0"),
117 ("Sec-Ch-Ua-Platform", r#""macOS""#),
118 ("Connection", "keep-alive"),
119 ]
120}
121
122pub fn chrome_143_form_headers() -> Vec<(&'static str, &'static str)> {
124 vec![
125 ("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36"),
126 ("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"),
127 ("Accept-Language", "en-US,en;q=0.9"),
128 ("Accept-Encoding", "gzip, deflate, br, zstd"),
129 ("Content-Type", "application/x-www-form-urlencoded"),
130 ("Sec-Fetch-Dest", "document"),
131 ("Sec-Fetch-Mode", "navigate"),
132 ("Sec-Fetch-Site", "same-origin"),
133 ("Sec-Ch-Ua", r#""Google Chrome";v="143", "Chromium";v="143", "Not A(Brand";v="99""#),
134 ("Sec-Ch-Ua-Mobile", "?0"),
135 ("Sec-Ch-Ua-Platform", r#""macOS""#),
136 ("Sec-Ch-Ua-Arch", r#""arm64""#),
137 ("Sec-Ch-Ua-Bitness", r#""64""#),
138 ("Sec-Ch-Ua-Full-Version-List", r#""Google Chrome";v="143.0.7499.40", "Chromium";v="143.0.7499.40", "Not A(Brand";v="99.0.0.0""#),
139 ("Sec-Ch-Ua-Model", r#""""#),
140 ("Sec-Ch-Ua-Platform-Version", r#""15.5.0""#),
141 ("Sec-Ch-Ua-Wow64", "?0"),
142 ("Upgrade-Insecure-Requests", "1"),
143 ("Connection", "keep-alive"),
144 ]
145}
146
147pub fn chrome_144_headers() -> Vec<(&'static str, &'static str)> {
149 vec![
150 ("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36"),
151 ("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"),
152 ("Accept-Language", "en-US,en;q=0.9"),
153 ("Accept-Encoding", "gzip, deflate, br, zstd"),
154 ("Sec-Fetch-Dest", "document"),
155 ("Sec-Fetch-Mode", "navigate"),
156 ("Sec-Fetch-Site", "none"),
157 ("Sec-Fetch-User", "?1"),
158 ("Sec-Ch-Ua", r#""Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144""#),
159 ("Sec-Ch-Ua-Mobile", "?0"),
160 ("Sec-Ch-Ua-Platform", r#""macOS""#),
161 ("Sec-Ch-Ua-Arch", r#""arm64""#),
162 ("Sec-Ch-Ua-Bitness", r#""64""#),
163 ("Sec-Ch-Ua-Full-Version-List", r#""Not(A:Brand";v="8.0.0.0", "Chromium";v="144.0.7559.133", "Google Chrome";v="144.0.7559.133""#),
164 ("Sec-Ch-Ua-Model", r#""""#),
165 ("Sec-Ch-Ua-Platform-Version", r#""15.5.0""#),
166 ("Sec-Ch-Ua-Wow64", "?0"),
167 ("Upgrade-Insecure-Requests", "1"),
168 ("Connection", "keep-alive"),
169 ]
170}
171
172pub fn chrome_144_ajax_headers() -> Vec<(&'static str, &'static str)> {
174 vec![
175 ("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36"),
176 ("Accept", "application/json, text/plain, */*"),
177 ("Accept-Language", "en-US,en;q=0.9"),
178 ("Accept-Encoding", "gzip, deflate, br, zstd"),
179 ("Content-Type", "application/json"),
180 ("Sec-Fetch-Dest", "empty"),
181 ("Sec-Fetch-Mode", "cors"),
182 ("Sec-Fetch-Site", "same-origin"),
183 ("Sec-Ch-Ua", r#""Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144""#),
184 ("Sec-Ch-Ua-Mobile", "?0"),
185 ("Sec-Ch-Ua-Platform", r#""macOS""#),
186 ("Connection", "keep-alive"),
187 ]
188}
189
190pub fn chrome_144_form_headers() -> Vec<(&'static str, &'static str)> {
192 vec![
193 ("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36"),
194 ("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"),
195 ("Accept-Language", "en-US,en;q=0.9"),
196 ("Accept-Encoding", "gzip, deflate, br, zstd"),
197 ("Content-Type", "application/x-www-form-urlencoded"),
198 ("Sec-Fetch-Dest", "document"),
199 ("Sec-Fetch-Mode", "navigate"),
200 ("Sec-Fetch-Site", "same-origin"),
201 ("Sec-Ch-Ua", r#""Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144""#),
202 ("Sec-Ch-Ua-Mobile", "?0"),
203 ("Sec-Ch-Ua-Platform", r#""macOS""#),
204 ("Sec-Ch-Ua-Arch", r#""arm64""#),
205 ("Sec-Ch-Ua-Bitness", r#""64""#),
206 ("Sec-Ch-Ua-Full-Version-List", r#""Not(A:Brand";v="8.0.0.0", "Chromium";v="144.0.7559.133", "Google Chrome";v="144.0.7559.133""#),
207 ("Sec-Ch-Ua-Model", r#""""#),
208 ("Sec-Ch-Ua-Platform-Version", r#""15.5.0""#),
209 ("Sec-Ch-Ua-Wow64", "?0"),
210 ("Upgrade-Insecure-Requests", "1"),
211 ("Connection", "keep-alive"),
212 ]
213}
214
215pub fn chrome_145_headers() -> Vec<(&'static str, &'static str)> {
217 vec![
218 ("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36"),
219 ("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"),
220 ("Accept-Language", "en-US,en;q=0.9"),
221 ("Accept-Encoding", "gzip, deflate, br, zstd"),
222 ("Sec-Fetch-Dest", "document"),
223 ("Sec-Fetch-Mode", "navigate"),
224 ("Sec-Fetch-Site", "none"),
225 ("Sec-Fetch-User", "?1"),
226 ("Sec-Ch-Ua", r#""Not:A-Brand";v="24", "Google Chrome";v="145", "Chromium";v="145""#),
227 ("Sec-Ch-Ua-Mobile", "?0"),
228 ("Sec-Ch-Ua-Platform", r#""macOS""#),
229 ("Sec-Ch-Ua-Arch", r#""arm64""#),
230 ("Sec-Ch-Ua-Bitness", r#""64""#),
231 ("Sec-Ch-Ua-Full-Version-List", r#""Not:A-Brand";v="24.0.0.0", "Google Chrome";v="145.0.7632.117", "Chromium";v="145.0.7632.117""#),
232 ("Sec-Ch-Ua-Model", r#""""#),
233 ("Sec-Ch-Ua-Platform-Version", r#""15.5.0""#),
234 ("Sec-Ch-Ua-Wow64", "?0"),
235 ("Upgrade-Insecure-Requests", "1"),
236 ("Connection", "keep-alive"),
237 ]
238}
239
240pub fn chrome_145_ajax_headers() -> Vec<(&'static str, &'static str)> {
242 vec![
243 ("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36"),
244 ("Accept", "application/json, text/plain, */*"),
245 ("Accept-Language", "en-US,en;q=0.9"),
246 ("Accept-Encoding", "gzip, deflate, br, zstd"),
247 ("Content-Type", "application/json"),
248 ("Sec-Fetch-Dest", "empty"),
249 ("Sec-Fetch-Mode", "cors"),
250 ("Sec-Fetch-Site", "same-origin"),
251 ("Sec-Ch-Ua", r#""Not:A-Brand";v="24", "Google Chrome";v="145", "Chromium";v="145""#),
252 ("Sec-Ch-Ua-Mobile", "?0"),
253 ("Sec-Ch-Ua-Platform", r#""macOS""#),
254 ("Connection", "keep-alive"),
255 ]
256}
257
258pub fn chrome_145_form_headers() -> Vec<(&'static str, &'static str)> {
260 vec![
261 ("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36"),
262 ("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"),
263 ("Accept-Language", "en-US,en;q=0.9"),
264 ("Accept-Encoding", "gzip, deflate, br, zstd"),
265 ("Content-Type", "application/x-www-form-urlencoded"),
266 ("Sec-Fetch-Dest", "document"),
267 ("Sec-Fetch-Mode", "navigate"),
268 ("Sec-Fetch-Site", "same-origin"),
269 ("Sec-Ch-Ua", r#""Not:A-Brand";v="24", "Google Chrome";v="145", "Chromium";v="145""#),
270 ("Sec-Ch-Ua-Mobile", "?0"),
271 ("Sec-Ch-Ua-Platform", r#""macOS""#),
272 ("Sec-Ch-Ua-Arch", r#""arm64""#),
273 ("Sec-Ch-Ua-Bitness", r#""64""#),
274 ("Sec-Ch-Ua-Full-Version-List", r#""Not:A-Brand";v="24.0.0.0", "Google Chrome";v="145.0.7632.117", "Chromium";v="145.0.7632.117""#),
275 ("Sec-Ch-Ua-Model", r#""""#),
276 ("Sec-Ch-Ua-Platform-Version", r#""15.5.0""#),
277 ("Sec-Ch-Ua-Wow64", "?0"),
278 ("Upgrade-Insecure-Requests", "1"),
279 ("Connection", "keep-alive"),
280 ]
281}
282
283pub fn chrome_146_headers() -> Vec<(&'static str, &'static str)> {
285 vec![
286 ("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36"),
287 ("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"),
288 ("Accept-Language", "en-US,en;q=0.9"),
289 ("Accept-Encoding", "gzip, deflate, br, zstd"),
290 ("Sec-Fetch-Dest", "document"),
291 ("Sec-Fetch-Mode", "navigate"),
292 ("Sec-Fetch-Site", "none"),
293 ("Sec-Fetch-User", "?1"),
294 ("Sec-Ch-Ua", r#""Chromium";v="146", "Not-A.Brand";v="99", "Google Chrome";v="146""#),
295 ("Sec-Ch-Ua-Mobile", "?0"),
296 ("Sec-Ch-Ua-Platform", r#""macOS""#),
297 ("Sec-Ch-Ua-Arch", r#""arm64""#),
298 ("Sec-Ch-Ua-Bitness", r#""64""#),
299 ("Sec-Ch-Ua-Full-Version-List", r#""Chromium";v="146.0.7680.165", "Not-A.Brand";v="99.0.0.0", "Google Chrome";v="146.0.7680.165""#),
300 ("Sec-Ch-Ua-Model", r#""""#),
301 ("Sec-Ch-Ua-Platform-Version", r#""15.5.0""#),
302 ("Sec-Ch-Ua-Wow64", "?0"),
303 ("Upgrade-Insecure-Requests", "1"),
304 ("Connection", "keep-alive"),
305 ]
306}
307
308pub fn chrome_146_ajax_headers() -> Vec<(&'static str, &'static str)> {
310 vec![
311 ("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36"),
312 ("Accept", "application/json, text/plain, */*"),
313 ("Accept-Language", "en-US,en;q=0.9"),
314 ("Accept-Encoding", "gzip, deflate, br, zstd"),
315 ("Content-Type", "application/json"),
316 ("Sec-Fetch-Dest", "empty"),
317 ("Sec-Fetch-Mode", "cors"),
318 ("Sec-Fetch-Site", "same-origin"),
319 ("Sec-Ch-Ua", r#""Chromium";v="146", "Not-A.Brand";v="99", "Google Chrome";v="146""#),
320 ("Sec-Ch-Ua-Mobile", "?0"),
321 ("Sec-Ch-Ua-Platform", r#""macOS""#),
322 ("Connection", "keep-alive"),
323 ]
324}
325
326pub fn chrome_146_form_headers() -> Vec<(&'static str, &'static str)> {
328 vec![
329 ("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36"),
330 ("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"),
331 ("Accept-Language", "en-US,en;q=0.9"),
332 ("Accept-Encoding", "gzip, deflate, br, zstd"),
333 ("Content-Type", "application/x-www-form-urlencoded"),
334 ("Sec-Fetch-Dest", "document"),
335 ("Sec-Fetch-Mode", "navigate"),
336 ("Sec-Fetch-Site", "same-origin"),
337 ("Sec-Ch-Ua", r#""Chromium";v="146", "Not-A.Brand";v="99", "Google Chrome";v="146""#),
338 ("Sec-Ch-Ua-Mobile", "?0"),
339 ("Sec-Ch-Ua-Platform", r#""macOS""#),
340 ("Sec-Ch-Ua-Arch", r#""arm64""#),
341 ("Sec-Ch-Ua-Bitness", r#""64""#),
342 ("Sec-Ch-Ua-Full-Version-List", r#""Chromium";v="146.0.7680.165", "Not-A.Brand";v="99.0.0.0", "Google Chrome";v="146.0.7680.165""#),
343 ("Sec-Ch-Ua-Model", r#""""#),
344 ("Sec-Ch-Ua-Platform-Version", r#""15.5.0""#),
345 ("Sec-Ch-Ua-Wow64", "?0"),
346 ("Upgrade-Insecure-Requests", "1"),
347 ("Connection", "keep-alive"),
348 ]
349}
350
351pub fn with_cookies(base: impl Into<Headers>, url: &str, jar: &CookieJar) -> Headers {
353 let mut headers: Headers = base.into();
354 headers.remove("cookie");
355 if let Some(cookie_header) = jar.build_cookie_header(url) {
356 headers.append("Cookie", cookie_header);
357 }
358 headers
359}
360
361pub fn with_origin(mut headers: Headers, origin: &str) -> Headers {
363 headers.remove("origin");
364 headers.append("Origin", origin.to_string());
365 headers
366}
367
368pub fn with_referer(mut headers: Headers, referer: &str) -> Headers {
370 headers.remove("referer");
371 headers.append("Referer", referer.to_string());
372 headers
373}
374
375pub fn headers_as_refs(headers: &Headers) -> Vec<(&str, &str)> {
377 headers.as_refs()
378}
379
380pub fn headers_to_owned(headers: Vec<(&'static str, &'static str)>) -> Vec<(String, String)> {
382 headers
383 .into_iter()
384 .map(|(k, v)| (k.to_string(), v.to_string()))
385 .collect()
386}
387
388#[derive(Debug, Clone, Default)]
393pub struct Headers {
394 headers: Vec<(String, String)>,
395}
396
397impl Headers {
398 pub fn new() -> Self {
399 Self::default()
400 }
401
402 pub fn from_vec(headers: Vec<(String, String)>) -> Self {
403 Self { headers }
404 }
405
406 pub fn from_static(headers: Vec<(&'static str, &'static str)>) -> Self {
407 Self {
408 headers: headers
409 .into_iter()
410 .map(|(k, v)| (k.to_string(), v.to_string()))
411 .collect(),
412 }
413 }
414
415 pub fn len(&self) -> usize {
416 self.headers.len()
417 }
418
419 pub fn is_empty(&self) -> bool {
420 self.headers.is_empty()
421 }
422
423 pub fn insert(&mut self, name: impl Into<String>, value: impl Into<String>) {
424 let name = name.into();
425 let name_lower = name.to_ascii_lowercase();
426 self.headers
427 .retain(|(k, _)| k.to_ascii_lowercase() != name_lower);
428 self.headers.push((name, value.into()));
429 }
430
431 pub fn append(&mut self, name: impl Into<String>, value: impl Into<String>) {
432 self.headers.push((name.into(), value.into()));
433 }
434
435 pub fn remove(&mut self, name: &str) -> Option<Vec<String>> {
436 let name_lower = name.to_ascii_lowercase();
437 let mut removed = Vec::new();
438 self.headers.retain(|(k, v)| {
439 if k.to_ascii_lowercase() == name_lower {
440 removed.push(v.clone());
441 false
442 } else {
443 true
444 }
445 });
446 if removed.is_empty() {
447 None
448 } else {
449 Some(removed)
450 }
451 }
452
453 pub fn get(&self, name: &str) -> Option<&str> {
454 let name_lower = name.to_ascii_lowercase();
455 self.headers.iter().find_map(|(k, v)| {
456 if k.to_ascii_lowercase() == name_lower {
457 Some(v.as_str())
458 } else {
459 None
460 }
461 })
462 }
463
464 pub fn get_all(&self, name: &str) -> Vec<&str> {
465 let name_lower = name.to_ascii_lowercase();
466 self.headers
467 .iter()
468 .filter_map(|(k, v)| {
469 if k.to_ascii_lowercase() == name_lower {
470 Some(v.as_str())
471 } else {
472 None
473 }
474 })
475 .collect()
476 }
477
478 pub fn contains(&self, name: &str) -> bool {
479 self.get(name).is_some()
480 }
481
482 pub fn iter(&self) -> impl Iterator<Item = (&str, &str)> {
483 self.headers.iter().map(|(k, v)| (k.as_str(), v.as_str()))
484 }
485
486 pub fn iter_ordered(&self) -> impl Iterator<Item = (&str, &str)> {
487 self.iter()
488 }
489
490 pub fn extend(&mut self, other: Headers) {
491 self.headers.extend(other.headers);
492 }
493
494 pub fn as_slice(&self) -> &[(String, String)] {
495 &self.headers
496 }
497
498 pub fn as_refs(&self) -> Vec<(&str, &str)> {
499 self.headers
500 .iter()
501 .map(|(k, v)| (k.as_str(), v.as_str()))
502 .collect()
503 }
504
505 pub fn to_vec(&self) -> Vec<(String, String)> {
506 self.headers.clone()
507 }
508}
509
510impl From<Vec<(String, String)>> for Headers {
511 fn from(value: Vec<(String, String)>) -> Self {
512 Headers::from_vec(value)
513 }
514}
515
516impl From<Vec<(&'static str, &'static str)>> for Headers {
517 fn from(value: Vec<(&'static str, &'static str)>) -> Self {
518 Headers::from_static(value)
519 }
520}
521
522impl From<HeaderMap> for Headers {
523 fn from(map: HeaderMap) -> Self {
524 let mut headers = Vec::new();
525 for (name, value) in map.iter() {
526 let value = value
527 .to_str()
528 .map(|s| s.to_string())
529 .unwrap_or_else(|_| String::from_utf8_lossy(value.as_bytes()).into_owned());
530 headers.push((name.as_str().to_string(), value));
531 }
532 Headers { headers }
533 }
534}
535
536#[derive(Debug, Clone)]
545pub struct OrderedHeaders {
546 headers: Vec<(String, String)>,
547}
548
549impl OrderedHeaders {
550 pub fn new(headers: Vec<(String, String)>) -> Self {
552 Self { headers }
553 }
554
555 pub fn chrome_navigation() -> Self {
558 Self::new(headers_to_owned(chrome_146_headers()))
559 }
560
561 pub fn firefox_navigation() -> Self {
563 Self::new(headers_to_owned(firefox_133_headers()))
564 }
565
566 pub fn headers(&self) -> &[(String, String)] {
568 &self.headers
569 }
570
571 pub fn ja4h_fingerprint(&self) -> String {
577 use sha2::{Digest, Sha256};
578
579 let header_names: Vec<String> = self
581 .headers
582 .iter()
583 .map(|(name, _)| name.to_lowercase())
584 .collect();
585
586 let names_str = header_names.join(",");
588
589 let mut hasher = Sha256::new();
591 hasher.update(names_str.as_bytes());
592 let hash = hasher.finalize();
593
594 let hash_str: String = hash[..3].iter().map(|b| format!("{:02x}", b)).collect();
596
597 format!("{}|{}", names_str, hash_str)
598 }
599
600 pub fn add(mut self, name: impl Into<String>, value: impl Into<String>) -> Self {
602 self.headers.push((name.into(), value.into()));
603 self
604 }
605
606 pub fn into_vec(self) -> Vec<(String, String)> {
608 self.headers
609 }
610}
611
612impl From<Vec<(String, String)>> for OrderedHeaders {
613 fn from(headers: Vec<(String, String)>) -> Self {
614 Self::new(headers)
615 }
616}
617
618impl From<OrderedHeaders> for Vec<(String, String)> {
619 fn from(oh: OrderedHeaders) -> Self {
620 oh.headers
621 }
622}
623
624pub fn firefox_133_headers() -> Vec<(&'static str, &'static str)> {
627 vec![
628 (
629 "User-Agent",
630 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:133.0) Gecko/20100101 Firefox/133.0",
631 ),
632 (
633 "Accept",
634 "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
635 ),
636 ("Accept-Language", "en-US,en;q=0.5"),
637 ("Accept-Encoding", "gzip, deflate, br, zstd"),
638 ("Sec-Fetch-Dest", "document"),
639 ("Sec-Fetch-Mode", "navigate"),
640 ("Sec-Fetch-Site", "none"),
641 ("Sec-Fetch-User", "?1"),
642 ("Upgrade-Insecure-Requests", "1"),
643 ("Connection", "keep-alive"),
644 ]
645}
646
647pub fn firefox_133_ajax_headers() -> Vec<(&'static str, &'static str)> {
649 vec![
650 (
651 "User-Agent",
652 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:133.0) Gecko/20100101 Firefox/133.0",
653 ),
654 ("Accept", "application/json, text/plain, */*"),
655 ("Accept-Language", "en-US,en;q=0.5"),
656 ("Accept-Encoding", "gzip, deflate, br, zstd"),
657 ("Content-Type", "application/json"),
658 ("Sec-Fetch-Dest", "empty"),
659 ("Sec-Fetch-Mode", "cors"),
660 ("Sec-Fetch-Site", "same-origin"),
661 ("Connection", "keep-alive"),
662 ]
663}
664
665pub fn firefox_133_form_headers() -> Vec<(&'static str, &'static str)> {
667 vec![
668 (
669 "User-Agent",
670 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:133.0) Gecko/20100101 Firefox/133.0",
671 ),
672 (
673 "Accept",
674 "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
675 ),
676 ("Accept-Language", "en-US,en;q=0.5"),
677 ("Accept-Encoding", "gzip, deflate, br, zstd"),
678 ("Content-Type", "application/x-www-form-urlencoded"),
679 ("Sec-Fetch-Dest", "document"),
680 ("Sec-Fetch-Mode", "navigate"),
681 ("Sec-Fetch-Site", "same-origin"),
682 ("Upgrade-Insecure-Requests", "1"),
683 ("Connection", "keep-alive"),
684 ]
685}