1#![allow(missing_debug_implementations)]
3#![allow(missing_docs)]
4
5#[macro_use]
6mod macros;
7mod chrome;
8mod firefox;
9mod okhttp;
10mod safari;
11
12use rquest::{EmulationProvider, EmulationProviderFactory};
13use serde::{Deserialize, Serialize};
14use typed_builder::TypedBuilder;
15
16#[cfg(feature = "emulation-rand")]
17use strum_macros::VariantArray;
18
19use chrome::*;
20use firefox::*;
21use okhttp::*;
22use safari::*;
23
24mod emulation_imports {
25 pub use super::{EmulationOS, EmulationOption};
26 pub use rquest::header::{
27 ACCEPT, ACCEPT_LANGUAGE, HeaderMap, HeaderName, HeaderValue, UPGRADE_INSECURE_REQUESTS,
28 USER_AGENT,
29 };
30 pub use rquest::{EmulationProvider, Http2Config};
31
32 #[cfg(all(feature = "gzip", feature = "deflate", feature = "brotli"))]
33 pub use rquest::header::ACCEPT_ENCODING;
34}
35
36mod tls_imports {
37 pub use rquest::{
38 AlpnProtos, AlpsProtos, CertCompressionAlgorithm, ExtensionType, SslCurve, TlsConfig,
39 TlsVersion,
40 };
41 pub use typed_builder::TypedBuilder;
42}
43
44mod http2_imports {
45 pub use rquest::PseudoOrder::{self, *};
46 pub use rquest::SettingsOrder::{self, *};
47 pub use rquest::{Priority, StreamDependency, StreamId};
48 pub use std::sync::LazyLock;
49}
50
51macro_rules! define_emulation_enum {
52 ($(#[$meta:meta])* $name:ident, $default_variant:ident, $($variant:ident => $rename:expr),*) => {
53 $(#[$meta])*
54 #[cfg(not(feature = "emulation-rand"))]
55 #[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)]
56 pub enum $name {
57 $(
58 #[serde(rename = $rename)]
59 $variant,
60 )*
61 }
62
63 #[cfg(not(feature = "emulation-rand"))]
64 impl Default for $name {
65 fn default() -> Self {
66 $name::$default_variant
67 }
68 }
69
70 $(#[$meta])*
71 #[cfg(feature = "emulation-rand")]
72 #[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize, VariantArray)]
73 pub enum $name {
74 $(
75 #[serde(rename = $rename)]
76 $variant,
77 )*
78 }
79
80 #[cfg(feature = "emulation-rand")]
81 impl Default for $name {
82 fn default() -> Self {
83 $name::$default_variant
84 }
85 }
86 };
87}
88
89define_emulation_enum!(
90 Emulation, Chrome133,
118 Chrome100 => "chrome_100",
119 Chrome101 => "chrome_101",
120 Chrome104 => "chrome_104",
121 Chrome105 => "chrome_105",
122 Chrome106 => "chrome_106",
123 Chrome107 => "chrome_107",
124 Chrome108 => "chrome_108",
125 Chrome109 => "chrome_109",
126 Chrome114 => "chrome_114",
127 Chrome116 => "chrome_116",
128 Chrome117 => "chrome_117",
129 Chrome118 => "chrome_118",
130 Chrome119 => "chrome_119",
131 Chrome120 => "chrome_120",
132 Chrome123 => "chrome_123",
133 Chrome124 => "chrome_124",
134 Chrome126 => "chrome_126",
135 Chrome127 => "chrome_127",
136 Chrome128 => "chrome_128",
137 Chrome129 => "chrome_129",
138 Chrome130 => "chrome_130",
139 Chrome131 => "chrome_131",
140 Chrome132 => "chrome_132",
141 Chrome133 => "chrome_133",
142 SafariIos17_2 => "safari_ios_17.2",
143 SafariIos17_4_1 => "safari_ios_17.4.1",
144 SafariIos16_5 => "safari_ios_16.5",
145 Safari15_3 => "safari_15.3",
146 Safari15_5 => "safari_15.5",
147 Safari15_6_1 => "safari_15.6.1",
148 Safari16 => "safari_16",
149 Safari16_5 => "safari_16.5",
150 Safari17_0 => "safari_17.0",
151 Safari17_2_1 => "safari_17.2.1",
152 Safari17_4_1 => "safari_17.4.1",
153 Safari17_5 => "safari_17.5",
154 Safari18 => "safari_18",
155 SafariIPad18 => "safari_ipad_18",
156 Safari18_2 => "safari_18.2",
157 SafariIos18_1_1 => "safari_ios_18.1.1",
158 OkHttp3_9 => "okhttp_3.9",
159 OkHttp3_11 => "okhttp_3.11",
160 OkHttp3_13 => "okhttp_3.13",
161 OkHttp3_14 => "okhttp_3.14",
162 OkHttp4_9 => "okhttp_4.9",
163 OkHttp4_10 => "okhttp_4.10",
164 OkHttp5 => "okhttp_5",
165 Edge101 => "edge_101",
166 Edge122 => "edge_122",
167 Edge127 => "edge_127",
168 Edge131 => "edge_131",
169 Firefox109 => "firefox_109",
170 Firefox117 => "firefox_117",
171 Firefox128 => "firefox_128",
172 Firefox133 => "firefox_133",
173 Firefox135 => "firefox_135",
174 FirefoxPrivate135 => "firefox_private_135",
175 FirefoxAndroid135 => "firefox_android_135"
176);
177
178impl EmulationProviderFactory for Emulation {
180 fn emulation(self) -> EmulationProvider {
181 EmulationOption::builder()
182 .emulation(self)
183 .build()
184 .emulation()
185 }
186}
187
188#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Deserialize, Serialize)]
214pub enum EmulationOS {
215 #[serde(rename = "windows")]
216 Windows,
217 #[serde(rename = "macos")]
218 #[default]
219 MacOS,
220 #[serde(rename = "linux")]
221 Linux,
222 #[serde(rename = "android")]
223 Android,
224 #[serde(rename = "ios")]
225 IOS,
226}
227
228impl EmulationOS {
230 #[inline]
231 fn platform(&self) -> &'static str {
232 match self {
233 EmulationOS::MacOS => "\"macOS\"",
234 EmulationOS::Linux => "\"Linux\"",
235 EmulationOS::Windows => "\"Windows\"",
236 EmulationOS::Android => "\"Android\"",
237 EmulationOS::IOS => "\"iOS\"",
238 }
239 }
240
241 #[inline]
242 fn is_mobile(&self) -> bool {
243 matches!(self, EmulationOS::Android | EmulationOS::IOS)
244 }
245}
246
247#[derive(Default, TypedBuilder)]
248pub struct EmulationOption {
249 #[builder(default)]
251 emulation: Emulation,
252
253 #[builder(default)]
255 emulation_os: EmulationOS,
256
257 #[builder(default = false)]
259 skip_http2: bool,
260
261 #[builder(default = false)]
263 skip_headers: bool,
264}
265
266impl EmulationProviderFactory for EmulationOption {
268 fn emulation(self) -> EmulationProvider {
269 emulation_match!(
270 self.emulation,
271 self,
272
273 Emulation::Chrome100 => v100::emulation,
274 Emulation::Chrome101 => v101::emulation,
275 Emulation::Chrome104 => v104::emulation,
276 Emulation::Chrome105 => v105::emulation,
277 Emulation::Chrome106 => v106::emulation,
278 Emulation::Chrome107 => v107::emulation,
279 Emulation::Chrome108 => v108::emulation,
280 Emulation::Chrome109 => v109::emulation,
281 Emulation::Chrome114 => v114::emulation,
282 Emulation::Chrome116 => v116::emulation,
283 Emulation::Chrome117 => v117::emulation,
284 Emulation::Chrome118 => v118::emulation,
285 Emulation::Chrome119 => v119::emulation,
286 Emulation::Chrome120 => v120::emulation,
287 Emulation::Chrome123 => v123::emulation,
288 Emulation::Chrome124 => v124::emulation,
289 Emulation::Chrome126 => v126::emulation,
290 Emulation::Chrome127 => v127::emulation,
291 Emulation::Chrome128 => v128::emulation,
292 Emulation::Chrome129 => v129::emulation,
293 Emulation::Chrome130 => v130::emulation,
294 Emulation::Chrome131 => v131::emulation,
295 Emulation::Chrome132 => v132::emulation,
296 Emulation::Chrome133 => v133::emulation,
297
298 Emulation::SafariIos17_2 => safari_ios_17_2::emulation,
299 Emulation::SafariIos17_4_1 => safari_ios_17_4_1::emulation,
300 Emulation::SafariIos16_5 => safari_ios_16_5::emulation,
301 Emulation::Safari15_3 => safari15_3::emulation,
302 Emulation::Safari15_5 => safari15_5::emulation,
303 Emulation::Safari15_6_1 => safari15_6_1::emulation,
304 Emulation::Safari16 => safari16::emulation,
305 Emulation::Safari16_5 => safari16_5::emulation,
306 Emulation::Safari17_0 => safari17_0::emulation,
307 Emulation::Safari17_2_1 => safari17_2_1::emulation,
308 Emulation::Safari17_4_1 => safari17_4_1::emulation,
309 Emulation::Safari17_5 => safari17_5::emulation,
310 Emulation::Safari18 => safari18::emulation,
311 Emulation::SafariIPad18 => safari_ipad_18::emulation,
312 Emulation::Safari18_2 => safari18_2::emulation,
313 Emulation::SafariIos18_1_1 => safari_ios_18_1_1::emulation,
314
315 Emulation::OkHttp3_9 => okhttp3_9::emulation,
316 Emulation::OkHttp3_11 => okhttp3_11::emulation,
317 Emulation::OkHttp3_13 => okhttp3_13::emulation,
318 Emulation::OkHttp3_14 => okhttp3_14::emulation,
319 Emulation::OkHttp4_9 => okhttp4_9::emulation,
320 Emulation::OkHttp4_10 => okhttp4_10::emulation,
321 Emulation::OkHttp5 => okhttp5::emulation,
322
323 Emulation::Edge101 => edge101::emulation,
324 Emulation::Edge122 => edge122::emulation,
325 Emulation::Edge127 => edge127::emulation,
326 Emulation::Edge131 => edge131::emulation,
327
328 Emulation::Firefox109 => ff109::emulation,
329 Emulation::Firefox117 => ff117::emulation,
330 Emulation::Firefox128 => ff128::emulation,
331 Emulation::Firefox133 => ff133::emulation,
332 Emulation::Firefox135 => ff135::emulation,
333 Emulation::FirefoxPrivate135 => ff_private_135::emulation,
334 Emulation::FirefoxAndroid135 => ff_android_135::emulation
335 )
336 }
337}