rquest_util/emulation/device/
mod.rs

1//! Emulation for different browsers.
2#![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
16use chrome::*;
17use firefox::*;
18use okhttp::*;
19use safari::*;
20
21mod emulation_imports {
22    pub use super::{EmulationOS, EmulationOption};
23    pub use http::{
24        HeaderMap, HeaderName, HeaderValue,
25        header::{ACCEPT, ACCEPT_LANGUAGE, UPGRADE_INSECURE_REQUESTS, USER_AGENT},
26    };
27    pub use rquest::{EmulationProvider, Http2Config};
28
29    #[cfg(all(feature = "gzip", feature = "deflate", feature = "brotli"))]
30    pub use http::header::ACCEPT_ENCODING;
31}
32
33mod tls_imports {
34    pub use rquest::{
35        AlpnProtos, AlpsProtos, CertCompressionAlgorithm, ExtensionType, SslCurve, TlsConfig,
36        TlsVersion,
37    };
38    pub use typed_builder::TypedBuilder;
39}
40
41mod http2_imports {
42    pub use rquest::PseudoOrder::{self, *};
43    pub use rquest::SettingsOrder::{self, *};
44    pub use rquest::{Priority, StreamDependency, StreamId};
45    pub use std::sync::LazyLock;
46}
47
48/// Represents different browser versions for impersonation.
49///
50/// The `Emulation` enum provides variants for different browser versions that can be used
51/// to emulation HTTP requests. Each variant corresponds to a specific browser version.
52///
53/// # Naming Convention
54///
55/// The naming convention for the variants follows the pattern `browser_version`, where
56/// `browser` is the name of the browser (e.g., `chrome`, `firefox`, `safari`) and `version`
57/// is the version number. For example, `Chrome100` represents Chrome version 100.
58///
59/// The serialized names of the variants use underscores to separate the browser name and
60/// version number, following the pattern `browser_version`. For example, `Chrome100` is
61/// serialized as `"chrome_100"`.
62///
63/// # Examples
64///
65/// ```rust
66/// use rquest_util::Emulation;
67///
68/// let emulation = Emulation::Chrome100;
69/// let serialized = serde_json::to_string(&emulation).unwrap();
70/// assert_eq!(serialized, "\"chrome_100\"");
71///
72/// let deserialized: Emulation = serde_json::from_str(&serialized).unwrap();
73/// assert_eq!(deserialized, Emulation::Chrome100);
74/// ```
75#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Deserialize, Serialize)]
76pub enum Emulation {
77    #[serde(rename = "chrome_100")]
78    Chrome100,
79    #[serde(rename = "chrome_101")]
80    Chrome101,
81    #[serde(rename = "chrome_104")]
82    Chrome104,
83    #[serde(rename = "chrome_105")]
84    Chrome105,
85    #[serde(rename = "chrome_106")]
86    Chrome106,
87    #[serde(rename = "chrome_107")]
88    Chrome107,
89    #[serde(rename = "chrome_108")]
90    Chrome108,
91    #[serde(rename = "chrome_109")]
92    Chrome109,
93    #[serde(rename = "chrome_114")]
94    Chrome114,
95    #[serde(rename = "chrome_116")]
96    Chrome116,
97    #[serde(rename = "chrome_117")]
98    Chrome117,
99    #[serde(rename = "chrome_118")]
100    Chrome118,
101    #[serde(rename = "chrome_119")]
102    Chrome119,
103    #[serde(rename = "chrome_120")]
104    Chrome120,
105    #[serde(rename = "chrome_123")]
106    Chrome123,
107    #[serde(rename = "chrome_124")]
108    Chrome124,
109    #[serde(rename = "chrome_126")]
110    Chrome126,
111    #[serde(rename = "chrome_127")]
112    Chrome127,
113    #[serde(rename = "chrome_128")]
114    Chrome128,
115    #[serde(rename = "chrome_129")]
116    Chrome129,
117    #[serde(rename = "chrome_130")]
118    Chrome130,
119    #[serde(rename = "chrome_131")]
120    Chrome131,
121    #[serde(rename = "chrome_132")]
122    Chrome132,
123    #[serde(rename = "chrome_133")]
124    #[default]
125    Chrome133,
126
127    #[serde(rename = "safari_ios_17.2")]
128    SafariIos17_2,
129    #[serde(rename = "safari_ios_17.4.1")]
130    SafariIos17_4_1,
131    #[serde(rename = "safari_ios_16.5")]
132    SafariIos16_5,
133    #[serde(rename = "safari_15.3")]
134    Safari15_3,
135    #[serde(rename = "safari_15.5")]
136    Safari15_5,
137    #[serde(rename = "safari_15.6.1")]
138    Safari15_6_1,
139    #[serde(rename = "safari_16")]
140    Safari16,
141    #[serde(rename = "safari_16.5")]
142    Safari16_5,
143    #[serde(rename = "safari_17.0")]
144    Safari17_0,
145    #[serde(rename = "safari_17.2.1")]
146    Safari17_2_1,
147    #[serde(rename = "safari_17.4.1")]
148    Safari17_4_1,
149    #[serde(rename = "safari_17.5")]
150    Safari17_5,
151    #[serde(rename = "safari_18")]
152    Safari18,
153    #[serde(rename = "safari_ipad_18")]
154    SafariIPad18,
155    #[serde(rename = "safari_18.2")]
156    Safari18_2,
157    #[serde(rename = "safari_ios_18.1.1")]
158    SafariIos18_1_1,
159
160    #[serde(rename = "okhttp_3.9")]
161    OkHttp3_9,
162    #[serde(rename = "okhttp_3.11")]
163    OkHttp3_11,
164    #[serde(rename = "okhttp_3.13")]
165    OkHttp3_13,
166    #[serde(rename = "okhttp_3.14")]
167    OkHttp3_14,
168    #[serde(rename = "okhttp_4.9")]
169    OkHttp4_9,
170    #[serde(rename = "okhttp_4.10")]
171    OkHttp4_10,
172    #[serde(rename = "okhttp_5")]
173    OkHttp5,
174
175    #[serde(rename = "edge_101")]
176    Edge101,
177    #[serde(rename = "edge_122")]
178    Edge122,
179    #[serde(rename = "edge_127")]
180    Edge127,
181    #[serde(rename = "edge_131")]
182    Edge131,
183
184    #[serde(rename = "firefox_109")]
185    Firefox109,
186    #[serde(rename = "firefox_117")]
187    Firefox117,
188    #[serde(rename = "firefox_128")]
189    Firefox128,
190    #[serde(rename = "firefox_133")]
191    Firefox133,
192    #[serde(rename = "firefox_135")]
193    Firefox135,
194    #[serde(rename = "firefox_private_135")]
195    FirefoxPrivate135,
196    #[serde(rename = "firefox_android_135")]
197    FirefoxAndroid135,
198}
199
200/// ======== Emulation impls ========
201impl EmulationProviderFactory for Emulation {
202    fn emulation(self) -> EmulationProvider {
203        EmulationOption::builder()
204            .emulation(self)
205            .build()
206            .emulation()
207    }
208}
209
210/// Represents different operating systems for impersonation.
211///
212/// The `EmulationOS` enum provides variants for different operating systems that can be used
213/// to emulation HTTP requests. Each variant corresponds to a specific operating system.
214///
215/// # Naming Convention
216///
217/// The naming convention for the variants follows the pattern `os_name`, where
218/// `os_name` is the name of the operating system (e.g., `windows`, `macos`, `linux`, `android`, `ios`).
219///
220/// The serialized names of the variants use lowercase letters to represent the operating system names.
221/// For example, `Windows` is serialized as `"windows"`.
222///
223/// # Examples
224///
225/// ```rust
226/// use rquest::EmulationOS;
227///
228/// let emulation_os = EmulationOS::Windows;
229/// let serialized = serde_json::to_string(&emulation_os).unwrap();
230/// assert_eq!(serialized, "\"windows\"");
231///
232/// let deserialized: EmulationOS = serde_json::from_str(&serialized).unwrap();
233/// assert_eq!(deserialized, EmulationOS::Windows);
234/// ```
235#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Deserialize, Serialize)]
236pub enum EmulationOS {
237    #[serde(rename = "windows")]
238    Windows,
239    #[serde(rename = "macos")]
240    #[default]
241    MacOS,
242    #[serde(rename = "linux")]
243    Linux,
244    #[serde(rename = "android")]
245    Android,
246    #[serde(rename = "ios")]
247    IOS,
248}
249
250/// ======== EmulationOS impls ========
251impl EmulationOS {
252    #[inline]
253    fn platform(&self) -> &'static str {
254        match self {
255            EmulationOS::MacOS => "\"macOS\"",
256            EmulationOS::Linux => "\"Linux\"",
257            EmulationOS::Windows => "\"Windows\"",
258            EmulationOS::Android => "\"Android\"",
259            EmulationOS::IOS => "\"iOS\"",
260        }
261    }
262
263    #[inline]
264    fn is_mobile(&self) -> bool {
265        matches!(self, EmulationOS::Android | EmulationOS::IOS)
266    }
267}
268
269#[derive(Default, TypedBuilder)]
270pub struct EmulationOption {
271    /// The browser version to emulation.
272    #[builder(default)]
273    emulation: Emulation,
274
275    /// The operating system.
276    #[builder(default)]
277    emulation_os: EmulationOS,
278
279    /// Whether to skip HTTP/2.
280    #[builder(default = false)]
281    skip_http2: bool,
282
283    /// Whether to skip headers.
284    #[builder(default = false)]
285    skip_headers: bool,
286}
287
288/// ======== EmulationOption impls ========
289impl EmulationProviderFactory for EmulationOption {
290    fn emulation(self) -> EmulationProvider {
291        emulation_match!(
292            self.emulation,
293            self,
294
295            Emulation::Chrome100 => v100::emulation,
296            Emulation::Chrome101 => v101::emulation,
297            Emulation::Chrome104 => v104::emulation,
298            Emulation::Chrome105 => v105::emulation,
299            Emulation::Chrome106 => v106::emulation,
300            Emulation::Chrome107 => v107::emulation,
301            Emulation::Chrome108 => v108::emulation,
302            Emulation::Chrome109 => v109::emulation,
303            Emulation::Chrome114 => v114::emulation,
304            Emulation::Chrome116 => v116::emulation,
305            Emulation::Chrome117 => v117::emulation,
306            Emulation::Chrome118 => v118::emulation,
307            Emulation::Chrome119 => v119::emulation,
308            Emulation::Chrome120 => v120::emulation,
309            Emulation::Chrome123 => v123::emulation,
310            Emulation::Chrome124 => v124::emulation,
311            Emulation::Chrome126 => v126::emulation,
312            Emulation::Chrome127 => v127::emulation,
313            Emulation::Chrome128 => v128::emulation,
314            Emulation::Chrome129 => v129::emulation,
315            Emulation::Chrome130 => v130::emulation,
316            Emulation::Chrome131 => v131::emulation,
317            Emulation::Chrome132 => v132::emulation,
318            Emulation::Chrome133 => v133::emulation,
319
320            Emulation::SafariIos17_2 => safari_ios_17_2::emulation,
321            Emulation::SafariIos17_4_1 => safari_ios_17_4_1::emulation,
322            Emulation::SafariIos16_5 => safari_ios_16_5::emulation,
323            Emulation::Safari15_3 => safari15_3::emulation,
324            Emulation::Safari15_5 => safari15_5::emulation,
325            Emulation::Safari15_6_1 => safari15_6_1::emulation,
326            Emulation::Safari16 => safari16::emulation,
327            Emulation::Safari16_5 => safari16_5::emulation,
328            Emulation::Safari17_0 => safari17_0::emulation,
329            Emulation::Safari17_2_1 => safari17_2_1::emulation,
330            Emulation::Safari17_4_1 => safari17_4_1::emulation,
331            Emulation::Safari17_5 => safari17_5::emulation,
332            Emulation::Safari18 => safari18::emulation,
333            Emulation::SafariIPad18 => safari_ipad_18::emulation,
334            Emulation::Safari18_2 => safari18_2::emulation,
335            Emulation::SafariIos18_1_1 => safari_ios_18_1_1::emulation,
336
337            Emulation::OkHttp3_9 => okhttp3_9::emulation,
338            Emulation::OkHttp3_11 => okhttp3_11::emulation,
339            Emulation::OkHttp3_13 => okhttp3_13::emulation,
340            Emulation::OkHttp3_14 => okhttp3_14::emulation,
341            Emulation::OkHttp4_9 => okhttp4_9::emulation,
342            Emulation::OkHttp4_10 => okhttp4_10::emulation,
343            Emulation::OkHttp5 => okhttp5::emulation,
344
345            Emulation::Edge101 => edge101::emulation,
346            Emulation::Edge122 => edge122::emulation,
347            Emulation::Edge127 => edge127::emulation,
348            Emulation::Edge131 => edge131::emulation,
349
350            Emulation::Firefox109 => ff109::emulation,
351            Emulation::Firefox117 => ff117::emulation,
352            Emulation::Firefox128 => ff128::emulation,
353            Emulation::Firefox133 => ff133::emulation,
354            Emulation::Firefox135 => ff135::emulation,
355            Emulation::FirefoxPrivate135 => ff_private_135::emulation,
356            Emulation::FirefoxAndroid135 => ff_android_135::emulation
357        )
358    }
359}