wreq 1.2.4 → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +3 -7
  3. data/Cargo.toml +6 -1
  4. data/crates/wreq-util/.github/FUNDING.yml +15 -0
  5. data/crates/wreq-util/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  6. data/crates/wreq-util/.github/ISSUE_TEMPLATE/custom.md +10 -0
  7. data/crates/wreq-util/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  8. data/crates/wreq-util/.github/dependabot.yml +22 -0
  9. data/crates/wreq-util/.github/workflows/ci.yml +82 -0
  10. data/crates/wreq-util/.github/workflows/release-plz.yml +52 -0
  11. data/crates/wreq-util/.gitignore +24 -0
  12. data/crates/wreq-util/CHANGELOG.md +74 -0
  13. data/crates/wreq-util/Cargo.toml +94 -0
  14. data/crates/wreq-util/LICENSE +201 -0
  15. data/crates/wreq-util/README.md +62 -0
  16. data/crates/wreq-util/examples/emulate.rs +39 -0
  17. data/crates/wreq-util/examples/tower_delay.rs +191 -0
  18. data/crates/wreq-util/release-plz.toml +2 -0
  19. data/crates/wreq-util/rustfmt.toml +5 -0
  20. data/crates/wreq-util/src/emulate/compress.rs +85 -0
  21. data/crates/wreq-util/src/emulate/macros.rs +370 -0
  22. data/crates/wreq-util/src/emulate/profile/chrome/header.rs +59 -0
  23. data/crates/wreq-util/src/emulate/profile/chrome/http2.rs +65 -0
  24. data/crates/wreq-util/src/emulate/profile/chrome/tls.rs +153 -0
  25. data/crates/wreq-util/src/emulate/profile/chrome.rs +2028 -0
  26. data/crates/wreq-util/src/emulate/profile/firefox/header.rs +21 -0
  27. data/crates/wreq-util/src/emulate/profile/firefox/http2.rs +113 -0
  28. data/crates/wreq-util/src/emulate/profile/firefox/tls.rs +253 -0
  29. data/crates/wreq-util/src/emulate/profile/firefox.rs +518 -0
  30. data/crates/wreq-util/src/emulate/profile/okhttp.rs +241 -0
  31. data/crates/wreq-util/src/emulate/profile/opera/header.rs +30 -0
  32. data/crates/wreq-util/src/emulate/profile/opera/http2.rs +50 -0
  33. data/crates/wreq-util/src/emulate/profile/opera/tls.rs +97 -0
  34. data/crates/wreq-util/src/emulate/profile/opera.rs +299 -0
  35. data/crates/wreq-util/src/emulate/profile/safari/header.rs +59 -0
  36. data/crates/wreq-util/src/emulate/profile/safari/http2.rs +116 -0
  37. data/crates/wreq-util/src/emulate/profile/safari/tls.rs +177 -0
  38. data/crates/wreq-util/src/emulate/profile/safari.rs +222 -0
  39. data/crates/wreq-util/src/emulate/profile.rs +47 -0
  40. data/crates/wreq-util/src/emulate.rs +369 -0
  41. data/crates/wreq-util/src/lib.rs +14 -0
  42. data/crates/wreq-util/src/rand.rs +24 -0
  43. data/crates/wreq-util/src/tower/delay/future.rs +43 -0
  44. data/crates/wreq-util/src/tower/delay/layer.rs +201 -0
  45. data/crates/wreq-util/src/tower/delay/service.rs +190 -0
  46. data/crates/wreq-util/src/tower/delay.rs +98 -0
  47. data/crates/wreq-util/src/tower.rs +7 -0
  48. data/crates/wreq-util/tests/client.rs +51 -0
  49. data/crates/wreq-util/tests/emulate_chrome.rs +270 -0
  50. data/crates/wreq-util/tests/emulate_firefox.rs +92 -0
  51. data/crates/wreq-util/tests/emulate_okhttp.rs +46 -0
  52. data/crates/wreq-util/tests/emulate_opera.rs +113 -0
  53. data/crates/wreq-util/tests/emulate_safari.rs +151 -0
  54. data/crates/wreq-util/tests/support/mod.rs +55 -0
  55. data/crates/wreq-util/tests/support/server.rs +232 -0
  56. data/examples/emulate_request.rb +1 -1
  57. data/lib/wreq.rb +20 -18
  58. data/lib/wreq_ruby/body.rb +3 -0
  59. data/lib/wreq_ruby/client.rb +18 -18
  60. data/lib/wreq_ruby/cookie.rb +2 -2
  61. data/lib/wreq_ruby/emulate.rb +3 -1
  62. data/lib/wreq_ruby/header.rb +205 -114
  63. data/lib/wreq_ruby/response.rb +28 -3
  64. data/src/emulate.rs +1 -0
  65. data/src/error.rs +2 -6
  66. data/src/header/helper.rs +112 -0
  67. data/src/header.rs +198 -133
  68. data/test/header_test.rb +228 -192
  69. data/test/stream_test.rb +36 -0
  70. metadata +54 -1
@@ -0,0 +1,21 @@
1
+ use super::*;
2
+
3
+ pub fn header_initializer(ua: &'static str) -> HeaderMap {
4
+ let mut headers = HeaderMap::new();
5
+ header_firefox_ua!(headers, ua);
6
+ header_firefox_accept!(headers);
7
+ header_firefox_sec_fetch!(headers);
8
+ headers
9
+ }
10
+
11
+ pub fn header_initializer_with_zstd(ua: &'static str) -> HeaderMap {
12
+ let mut headers = HeaderMap::new();
13
+ header_firefox_ua!(headers, ua);
14
+ header_firefox_accept!(zstd, headers);
15
+ header_firefox_sec_fetch!(headers);
16
+ headers.insert(
17
+ HeaderName::from_static("priority"),
18
+ HeaderValue::from_static("u=0, i"),
19
+ );
20
+ headers
21
+ }
@@ -0,0 +1,113 @@
1
+ macro_rules! headers_stream_dependency {
2
+ (1) => {
3
+ StreamDependency::new(StreamId::zero(), 21, false)
4
+ };
5
+ (2) => {
6
+ StreamDependency::new(StreamId::from(13), 21, false)
7
+ };
8
+ }
9
+
10
+ macro_rules! pseudo_order {
11
+ () => {
12
+ PseudoOrder::builder()
13
+ .extend([
14
+ PseudoId::Method,
15
+ PseudoId::Path,
16
+ PseudoId::Authority,
17
+ PseudoId::Scheme,
18
+ ])
19
+ .build()
20
+ };
21
+ }
22
+
23
+ macro_rules! settings_order {
24
+ () => {
25
+ SettingsOrder::builder()
26
+ .extend([
27
+ SettingId::HeaderTableSize,
28
+ SettingId::EnablePush,
29
+ SettingId::MaxConcurrentStreams,
30
+ SettingId::InitialWindowSize,
31
+ SettingId::MaxFrameSize,
32
+ SettingId::MaxHeaderListSize,
33
+ SettingId::EnableConnectProtocol,
34
+ SettingId::NoRfc7540Priorities,
35
+ ])
36
+ .build()
37
+ };
38
+ }
39
+
40
+ macro_rules! http2_options {
41
+ (@base $builder:expr) => {
42
+ $builder
43
+ .initial_window_size(131072)
44
+ .max_frame_size(16384)
45
+ .initial_connection_window_size(12517377 + 65535)
46
+ .headers_pseudo_order(pseudo_order!())
47
+ .settings_order(settings_order!())
48
+ };
49
+
50
+ (1) => {
51
+ http2_options!(@base Http2Options::builder())
52
+ .initial_stream_id(3)
53
+ .header_table_size(65536)
54
+ .enable_push(false)
55
+ .headers_stream_dependency(headers_stream_dependency!(1))
56
+ .build()
57
+ };
58
+ (2) => {
59
+ http2_options!(@base Http2Options::builder())
60
+ .initial_stream_id(15)
61
+ .header_table_size(65536)
62
+ .headers_stream_dependency(headers_stream_dependency!(2))
63
+ .priorities(
64
+ Priorities::builder()
65
+ .extend([
66
+ Priority::new(
67
+ StreamId::from(3),
68
+ StreamDependency::new(StreamId::zero(), 200, false),
69
+ ),
70
+ Priority::new(
71
+ StreamId::from(5),
72
+ StreamDependency::new(StreamId::zero(), 100, false),
73
+ ),
74
+ Priority::new(
75
+ StreamId::from(7),
76
+ StreamDependency::new(StreamId::zero(), 0, false),
77
+ ),
78
+ Priority::new(
79
+ StreamId::from(9),
80
+ StreamDependency::new(StreamId::from(7), 0, false),
81
+ ),
82
+ Priority::new(
83
+ StreamId::from(11),
84
+ StreamDependency::new(StreamId::from(3), 0, false),
85
+ ),
86
+ Priority::new(
87
+ StreamId::from(13),
88
+ StreamDependency::new(StreamId::zero(), 240, false),
89
+ ),
90
+ ])
91
+ .build(),
92
+ )
93
+ .build()
94
+ };
95
+ (3) => {
96
+ http2_options!(@base Http2Options::builder())
97
+ .initial_stream_id(3)
98
+ .header_table_size(65536)
99
+ .enable_push(false)
100
+ .max_concurrent_streams(0)
101
+ .headers_stream_dependency(headers_stream_dependency!(1))
102
+ .build()
103
+ };
104
+ (4) => {
105
+ http2_options!(@base Http2Options::builder())
106
+ .initial_stream_id(3)
107
+ .header_table_size(4096)
108
+ .enable_push(false)
109
+ .initial_window_size(32768)
110
+ .headers_stream_dependency(headers_stream_dependency!(1))
111
+ .build()
112
+ };
113
+ }
@@ -0,0 +1,253 @@
1
+ use super::*;
2
+
3
+ macro_rules! tls_options {
4
+ (@build $builder:expr) => {
5
+ $builder.build().into()
6
+ };
7
+
8
+ (@base $builder:expr, $cipher_list:expr, $curves:expr) => {
9
+ $builder
10
+ .cipher_list($cipher_list)
11
+ .curves_list($curves)
12
+ };
13
+
14
+ (1, $cipher_list:expr, $curves:expr, $key_shares:expr) => {
15
+ tls_options!(@build tls_options!(@base FirefoxTlsConfig::builder(), $cipher_list, $curves)
16
+ .enable_ech_grease(true)
17
+ .pre_shared_key(true)
18
+ .psk_skip_session_tickets(true)
19
+ .key_shares($key_shares)
20
+ .certificate_compressors(CERTIFICATE_COMPRESSORS))
21
+ };
22
+ (2, $cipher_list:expr, $curves:expr) => {
23
+ tls_options!(@build tls_options!(@base FirefoxTlsConfig::builder(), $cipher_list, $curves))
24
+ };
25
+ (3, $cipher_list:expr, $curves:expr, $key_shares:expr) => {
26
+ tls_options!(@build tls_options!(@base FirefoxTlsConfig::builder(), $cipher_list, $curves)
27
+ .session_ticket(false)
28
+ .enable_ech_grease(true)
29
+ .psk_dhe_ke(false)
30
+ .key_shares($key_shares))
31
+ };
32
+ (4, $cipher_list:expr, $curves:expr, $key_shares:expr) => {
33
+ tls_options!(@build tls_options!(@base FirefoxTlsConfig::builder(), $cipher_list, $curves)
34
+ .enable_ech_grease(true)
35
+ .enable_signed_cert_timestamps(true)
36
+ .session_ticket(true)
37
+ .pre_shared_key(true)
38
+ .psk_skip_session_tickets(true)
39
+ .key_shares($key_shares)
40
+ .certificate_compressors(CERTIFICATE_COMPRESSORS))
41
+ };
42
+ (5, $cipher_list:expr, $curves:expr, $key_shares:expr) => {
43
+ tls_options!(@build tls_options!(@base FirefoxTlsConfig::builder(), $cipher_list, $curves)
44
+ .enable_ech_grease(true)
45
+ .pre_shared_key(true)
46
+ .psk_skip_session_tickets(true)
47
+ .key_shares($key_shares)
48
+ .certificate_compressors(CERTIFICATE_COMPRESSORS))
49
+ };
50
+ (6, $cipher_list:expr, $curves:expr, $key_shares:expr) => {
51
+ tls_options!(@build tls_options!(@base FirefoxTlsConfig::builder(), $cipher_list, $curves)
52
+ .enable_ech_grease(true)
53
+ .enable_signed_cert_timestamps(true)
54
+ .session_ticket(false)
55
+ .psk_dhe_ke(false)
56
+ .key_shares($key_shares)
57
+ .certificate_compressors(CERTIFICATE_COMPRESSORS))
58
+ };
59
+ }
60
+
61
+ pub const CURVES_1: &str = join!(
62
+ ":",
63
+ "X25519",
64
+ "P-256",
65
+ "P-384",
66
+ "P-521",
67
+ "ffdhe2048",
68
+ "ffdhe3072"
69
+ );
70
+
71
+ pub const CURVES_2: &str = join!(
72
+ ":",
73
+ "X25519MLKEM768",
74
+ "X25519",
75
+ "P-256",
76
+ "P-384",
77
+ "P-521",
78
+ "ffdhe2048",
79
+ "ffdhe3072"
80
+ );
81
+
82
+ pub const KEY_SHARES_1: &[KeyShare] = &[KeyShare::X25519, KeyShare::P256];
83
+
84
+ pub const KEY_SHARES_2: &[KeyShare] =
85
+ &[KeyShare::X25519_MLKEM768, KeyShare::X25519, KeyShare::P256];
86
+
87
+ pub const CIPHER_LIST_1: &str = join!(
88
+ ":",
89
+ "TLS_AES_128_GCM_SHA256",
90
+ "TLS_CHACHA20_POLY1305_SHA256",
91
+ "TLS_AES_256_GCM_SHA384",
92
+ "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
93
+ "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
94
+ "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
95
+ "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
96
+ "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
97
+ "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
98
+ "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
99
+ "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
100
+ "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
101
+ "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
102
+ "TLS_RSA_WITH_AES_128_GCM_SHA256",
103
+ "TLS_RSA_WITH_AES_256_GCM_SHA384",
104
+ "TLS_RSA_WITH_AES_128_CBC_SHA",
105
+ "TLS_RSA_WITH_AES_256_CBC_SHA"
106
+ );
107
+
108
+ pub const CIPHER_LIST_2: &str = join!(
109
+ ":",
110
+ "TLS_AES_128_GCM_SHA256",
111
+ "TLS_CHACHA20_POLY1305_SHA256",
112
+ "TLS_AES_256_GCM_SHA384",
113
+ "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
114
+ "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
115
+ "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
116
+ "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
117
+ "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
118
+ "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
119
+ "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
120
+ "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
121
+ "TLS_RSA_WITH_AES_128_GCM_SHA256",
122
+ "TLS_RSA_WITH_AES_256_GCM_SHA384",
123
+ "TLS_RSA_WITH_AES_128_CBC_SHA",
124
+ "TLS_RSA_WITH_AES_256_CBC_SHA"
125
+ );
126
+
127
+ pub const SIGALGS_LIST: &str = join!(
128
+ ":",
129
+ "ecdsa_secp256r1_sha256",
130
+ "ecdsa_secp384r1_sha384",
131
+ "ecdsa_secp521r1_sha512",
132
+ "rsa_pss_rsae_sha256",
133
+ "rsa_pss_rsae_sha384",
134
+ "rsa_pss_rsae_sha512",
135
+ "rsa_pkcs1_sha256",
136
+ "rsa_pkcs1_sha384",
137
+ "rsa_pkcs1_sha512",
138
+ "ecdsa_sha1",
139
+ "rsa_pkcs1_sha1"
140
+ );
141
+
142
+ pub const CERTIFICATE_COMPRESSORS: &[&'static dyn CertificateCompressor] =
143
+ &[&ZlibCompressor, &BrotliCompressor, &ZstdCompressor];
144
+
145
+ pub const DELEGATED_CREDENTIALS: &str = join!(
146
+ ":",
147
+ "ecdsa_secp256r1_sha256",
148
+ "ecdsa_secp384r1_sha384",
149
+ "ecdsa_secp521r1_sha512",
150
+ "ecdsa_sha1"
151
+ );
152
+
153
+ pub const RECORD_SIZE_LIMIT: u16 = 0x4001;
154
+
155
+ pub const EXTENSION_PERMUTATION_INDICES: &[ExtensionType] = &[
156
+ ExtensionType::SERVER_NAME,
157
+ ExtensionType::EXTENDED_MASTER_SECRET,
158
+ ExtensionType::RENEGOTIATE,
159
+ ExtensionType::SUPPORTED_GROUPS,
160
+ ExtensionType::EC_POINT_FORMATS,
161
+ ExtensionType::SESSION_TICKET,
162
+ ExtensionType::APPLICATION_LAYER_PROTOCOL_NEGOTIATION,
163
+ ExtensionType::STATUS_REQUEST,
164
+ ExtensionType::DELEGATED_CREDENTIAL,
165
+ ExtensionType::CERTIFICATE_TIMESTAMP,
166
+ ExtensionType::KEY_SHARE,
167
+ ExtensionType::SUPPORTED_VERSIONS,
168
+ ExtensionType::SIGNATURE_ALGORITHMS,
169
+ ExtensionType::PSK_KEY_EXCHANGE_MODES,
170
+ ExtensionType::RECORD_SIZE_LIMIT,
171
+ ExtensionType::CERT_COMPRESSION,
172
+ ExtensionType::ENCRYPTED_CLIENT_HELLO,
173
+ ];
174
+
175
+ #[derive(TypedBuilder)]
176
+ pub struct FirefoxTlsConfig {
177
+ #[builder(default = SIGALGS_LIST)]
178
+ sigalgs_list: &'static str,
179
+
180
+ #[builder(setter(into))]
181
+ cipher_list: &'static str,
182
+
183
+ #[builder(setter(into))]
184
+ curves_list: &'static str,
185
+
186
+ #[builder(default, setter(into))]
187
+ key_shares: Option<&'static [KeyShare]>,
188
+
189
+ #[builder(default = true)]
190
+ session_ticket: bool,
191
+
192
+ #[builder(default = false, setter(into))]
193
+ enable_ech_grease: bool,
194
+
195
+ #[builder(default = false, setter(into))]
196
+ enable_signed_cert_timestamps: bool,
197
+
198
+ #[builder(default = false, setter(into))]
199
+ pre_shared_key: bool,
200
+
201
+ #[builder(default = false, setter(into))]
202
+ psk_skip_session_tickets: bool,
203
+
204
+ #[builder(default = DELEGATED_CREDENTIALS, setter(into))]
205
+ delegated_credentials: &'static str,
206
+
207
+ #[builder(default = RECORD_SIZE_LIMIT, setter(into))]
208
+ record_size_limit: u16,
209
+
210
+ #[builder(default = true, setter(into))]
211
+ psk_dhe_ke: bool,
212
+
213
+ #[builder(default, setter(into))]
214
+ certificate_compressors: Option<&'static [&'static dyn CertificateCompressor]>,
215
+
216
+ #[builder(default = EXTENSION_PERMUTATION_INDICES, setter(into))]
217
+ extension_permutation: &'static [ExtensionType],
218
+ }
219
+
220
+ impl From<FirefoxTlsConfig> for TlsOptions {
221
+ fn from(val: FirefoxTlsConfig) -> Self {
222
+ let mut builder = TlsOptions::builder()
223
+ .curves_list(val.curves_list)
224
+ .sigalgs_list(val.sigalgs_list)
225
+ .cipher_list(val.cipher_list)
226
+ .session_ticket(val.session_ticket)
227
+ .delegated_credentials(val.delegated_credentials)
228
+ .record_size_limit(val.record_size_limit)
229
+ .enable_ocsp_stapling(true)
230
+ .enable_ech_grease(val.enable_ech_grease)
231
+ .enable_signed_cert_timestamps(val.enable_signed_cert_timestamps)
232
+ .alpn_protocols([AlpnProtocol::HTTP2, AlpnProtocol::HTTP1])
233
+ .min_tls_version(TlsVersion::TLS_1_2)
234
+ .max_tls_version(TlsVersion::TLS_1_3)
235
+ .pre_shared_key(val.pre_shared_key)
236
+ .psk_skip_session_ticket(val.psk_skip_session_tickets)
237
+ .psk_dhe_ke(val.psk_dhe_ke)
238
+ .preserve_tls13_cipher_list(true)
239
+ .extension_permutation(val.extension_permutation)
240
+ .aes_hw_override(true)
241
+ .random_aes_hw_override(true);
242
+
243
+ if let Some(key_shares) = val.key_shares {
244
+ builder = builder.key_shares(key_shares)
245
+ }
246
+
247
+ if let Some(certificate_compressors) = val.certificate_compressors {
248
+ builder = builder.certificate_compressors(certificate_compressors)
249
+ }
250
+
251
+ builder.build()
252
+ }
253
+ }