rquest_util/emulation/
mod.rs

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