wreq_util/emulate/profile/
okhttp.rs1use super::*;
2
3const CURVES: &str = join!(":", "X25519", "P-256", "P-384");
4
5const SIGALGS_LIST: &str = join!(
6 ":",
7 "ecdsa_secp256r1_sha256",
8 "rsa_pss_rsae_sha256",
9 "rsa_pkcs1_sha256",
10 "ecdsa_secp384r1_sha384",
11 "rsa_pss_rsae_sha384",
12 "rsa_pkcs1_sha384",
13 "rsa_pss_rsae_sha512",
14 "rsa_pkcs1_sha512",
15 "rsa_pkcs1_sha1"
16);
17
18const CIPHER_LIST: &str = join!(
19 ":",
20 "TLS_AES_128_GCM_SHA256",
21 "TLS_AES_256_GCM_SHA384",
22 "TLS_CHACHA20_POLY1305_SHA256",
23 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
24 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
25 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
26 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
27 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
28 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
29 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
30 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
31 "TLS_RSA_WITH_AES_128_GCM_SHA256",
32 "TLS_RSA_WITH_AES_256_GCM_SHA384",
33 "TLS_RSA_WITH_AES_128_CBC_SHA",
34 "TLS_RSA_WITH_AES_256_CBC_SHA",
35 "TLS_RSA_WITH_3DES_EDE_CBC_SHA"
36);
37
38#[derive(TypedBuilder)]
39struct OkHttpTlsConfig {
40 #[builder(default = CURVES)]
41 curves: &'static str,
42
43 #[builder(default = SIGALGS_LIST)]
44 sigalgs_list: &'static str,
45
46 cipher_list: &'static str,
47}
48
49impl From<OkHttpTlsConfig> for TlsOptions {
50 fn from(val: OkHttpTlsConfig) -> Self {
51 TlsOptions::builder()
52 .enable_ocsp_stapling(true)
53 .curves_list(val.curves)
54 .sigalgs_list(val.sigalgs_list)
55 .cipher_list(val.cipher_list)
56 .min_tls_version(TlsVersion::TLS_1_2)
57 .max_tls_version(TlsVersion::TLS_1_3)
58 .aes_hw_override(true)
59 .build()
60 }
61}
62
63macro_rules! mod_generator {
64 ($mod_name:ident, $cipher:expr, $ua:expr) => {
65 pub(crate) mod $mod_name {
66 use super::*;
67
68 pub fn emulation(emulation: Emulation) -> wreq::Emulation {
69 build_emulation(stringify!($mod_name), emulation, $cipher, $ua)
70 }
71 }
72 };
73}
74
75fn build_emulation(
76 group: &'static str,
77 emulation: Emulation,
78 cipher_list: &'static str,
79 user_agent: &'static str,
80) -> wreq::Emulation {
81 let tls_options = OkHttpTlsConfig::builder()
82 .cipher_list(cipher_list)
83 .build()
84 .into();
85
86 let http2_options = emulation.http2.then(|| {
87 let settings_order = SettingsOrder::builder()
88 .extend([
89 SettingId::HeaderTableSize,
90 SettingId::EnablePush,
91 SettingId::MaxConcurrentStreams,
92 SettingId::InitialWindowSize,
93 SettingId::MaxFrameSize,
94 SettingId::MaxHeaderListSize,
95 SettingId::EnableConnectProtocol,
96 SettingId::NoRfc7540Priorities,
97 ])
98 .build();
99
100 Http2Options::builder()
101 .initial_window_size(16777216)
102 .initial_connection_window_size(16777216)
103 .headers_pseudo_order(
104 PseudoOrder::builder()
105 .extend([
106 PseudoId::Method,
107 PseudoId::Path,
108 PseudoId::Authority,
109 PseudoId::Scheme,
110 ])
111 .build(),
112 )
113 .settings_order(settings_order)
114 .build()
115 });
116
117 let headers = emulation.headers.then(|| {
118 let mut headers = HeaderMap::new();
119 headers.insert(ACCEPT, HeaderValue::from_static("*/*"));
120 headers.insert(ACCEPT_LANGUAGE, HeaderValue::from_static("en-US,en;q=0.9"));
121 headers.insert(USER_AGENT, HeaderValue::from_static(user_agent));
122 #[cfg(feature = "emulation-compression")]
123 headers.insert(ACCEPT_ENCODING, HeaderValue::from_static("gzip"));
124 headers
125 });
126
127 build_standard_emulation(group, tls_options, http2_options, headers)
128}
129
130mod_generator!(
131 okhttp3_9,
132 join!(
133 ":",
134 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
135 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
136 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
137 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
138 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
139 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
140 "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
141 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
142 "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
143 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
144 "TLS_RSA_WITH_AES_128_GCM_SHA256",
145 "TLS_RSA_WITH_AES_256_GCM_SHA384",
146 "TLS_RSA_WITH_AES_128_CBC_SHA",
147 "TLS_RSA_WITH_AES_256_CBC_SHA",
148 "TLS_RSA_WITH_3DES_EDE_CBC_SHA"
149 ),
150 "MaiMemo/4.4.50_639 okhttp/3.9 Android/5.0 Channel/WanDouJia Device/alps+M8+Emulator (armeabi-v7a) Screen/4.44 Resolution/480x800 DId/aa6cde19def3806806d5374c4e5fd617 RAM/0.94 ROM/4.91 Theme/Day"
151);
152
153mod_generator!(
154 okhttp3_11,
155 join!(
156 ":",
157 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
158 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
159 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
160 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
161 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
162 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
163 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
164 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
165 "TLS_RSA_WITH_AES_128_GCM_SHA256",
166 "TLS_RSA_WITH_AES_256_GCM_SHA384",
167 "TLS_RSA_WITH_AES_128_CBC_SHA",
168 "TLS_RSA_WITH_AES_256_CBC_SHA",
169 "TLS_RSA_WITH_3DES_EDE_CBC_SHA"
170 ),
171 "NRC Audio/2.0.6 (nl.nrc.audio; build:36; Android 12; Sdk:31; Manufacturer:motorola; Model: moto g72) OkHttp/3.11.0"
172);
173
174mod_generator!(
175 okhttp3_13,
176 join!(
177 ":",
178 "TLS_AES_128_GCM_SHA256",
179 "TLS_AES_256_GCM_SHA384",
180 "TLS_CHACHA20_POLY1305_SHA256",
181 "TLS_AES_128_CCM_SHA256",
182 "TLS_AES_256_CCM_8_SHA256",
183 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
184 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
185 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
186 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
187 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
188 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
189 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
190 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
191 "TLS_RSA_WITH_AES_128_GCM_SHA256",
192 "TLS_RSA_WITH_AES_256_GCM_SHA384",
193 "TLS_RSA_WITH_AES_128_CBC_SHA",
194 "TLS_RSA_WITH_AES_256_CBC_SHA",
195 "TLS_RSA_WITH_3DES_EDE_CBC_SHA"
196 ),
197 "GM-Android/6.112.2 (240590300; M:Google Pixel 7a; O:34; D:2b045e03986fa6dc) ObsoleteUrlFactory/1.0 OkHttp/3.13.0"
198);
199
200mod_generator!(
201 okhttp3_14,
202 CIPHER_LIST,
203 "DS podcast/2.0.1 (be.standaard.audio; build:9; Android 11; Sdk:30; Manufacturer:samsung; Model: SM-A405FN) OkHttp/3.14.0"
204);
205
206mod_generator!(
207 okhttp4_10,
208 CIPHER_LIST,
209 "GM-Android/6.112.2 (240590300; M:samsung SM-G781U1; O:33; D:edb34792871638d8) ObsoleteUrlFactory/1.0 OkHttp/4.10.0"
210);
211
212mod_generator!(
213 okhttp4_9,
214 join!(
215 ":",
216 "TLS_AES_128_GCM_SHA256",
217 "TLS_AES_256_GCM_SHA384",
218 "TLS_CHACHA20_POLY1305_SHA256",
219 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
220 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
221 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
222 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
223 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
224 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
225 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
226 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
227 "TLS_RSA_WITH_AES_128_GCM_SHA256",
228 "TLS_RSA_WITH_AES_256_GCM_SHA384",
229 "TLS_RSA_WITH_AES_128_CBC_SHA",
230 "TLS_RSA_WITH_AES_256_CBC_SHA"
231 ),
232 "GM-Android/6.111.1 (240460200; M:motorola moto g power (2021); O:30; D:76ba9f6628d198c8) ObsoleteUrlFactory/1.0 OkHttp/4.9"
233);
234
235mod_generator!(okhttp4_12, CIPHER_LIST, "okhttp/4.12.0");
236
237mod_generator!(
238 okhttp5,
239 CIPHER_LIST,
240 "NRC Audio/2.0.6 (nl.nrc.audio; build:36; Android 14; Sdk:34; Manufacturer:OnePlus; Model: CPH2609) OkHttp/5.0.0-alpha2"
241);