wreq 1.3.0 → 1.3.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a684244b1b3a988034a958ba6d5be4bd1c3233a958834eb103cabf8b57c7c7d2
4
- data.tar.gz: 2246ef7c885c1d4c429b1a0630795b8fe24bd1923dd4205267dd727ff552bb90
3
+ metadata.gz: '08bcba0b4518afc9f22ffcad92b7d162b481def8e63e69187bfa7aa846454209'
4
+ data.tar.gz: 32b0214db233dd726b885319dfaed9d0f8f12b46771d2c28ecf7c33ff1bfd8b9
5
5
  SHA512:
6
- metadata.gz: 4a1e164422249f5cc1df7d1259879e640c4e822ef3e9e2d0d67c11128e7f90c023119ddb6d1610a098b1d2c43657f72cdf0f0780f29f80f81e58be6b2cf66f72
7
- data.tar.gz: 8298504fd0e17008572c3d0a7ed0ee1ef949bbce9c88a73729fcece75ba87fb54c43ce38fa1ae961fcf297db8e0c2ca58b528155d14aac588ee23499255b860e
6
+ metadata.gz: '089ffdaa199e49037866fecbb76b912b1c817a59309e04a6c568a3c4883d85a73d3bb0bddb96a77a2bf6bb47376264c59ea851099923f23d0902cefbd8b17b84'
7
+ data.tar.gz: ba288883fa7a79780599e15935f216fde210f1b48ed058877e200ed8aa0e7c4793e0deaa6b3134784e330cf6e40a0411076d964703f7879ab0e0d4087f82e009
data/Cargo.lock CHANGED
@@ -32,12 +32,6 @@ dependencies = [
32
32
  "alloc-no-stdlib",
33
33
  ]
34
34
 
35
- [[package]]
36
- name = "allocator-api2"
37
- version = "0.2.21"
38
- source = "registry+https://github.com/rust-lang/crates.io-index"
39
- checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
40
-
41
35
  [[package]]
42
36
  name = "arc-swap"
43
37
  version = "1.9.2"
@@ -83,6 +77,23 @@ dependencies = [
83
77
  "syn 2.0.119",
84
78
  ]
85
79
 
80
+ [[package]]
81
+ name = "bindgen"
82
+ version = "0.73.2"
83
+ source = "registry+https://github.com/rust-lang/crates.io-index"
84
+ checksum = "787ef8ef523575546b106a58213d6e6b06198a05c2f757258c68a74273670cfa"
85
+ dependencies = [
86
+ "bitflags",
87
+ "cexpr",
88
+ "clang-sys",
89
+ "proc-macro2",
90
+ "quote",
91
+ "regex",
92
+ "rustc-hash",
93
+ "shlex 2.0.1",
94
+ "syn 2.0.119",
95
+ ]
96
+
86
97
  [[package]]
87
98
  name = "bitflags"
88
99
  version = "2.13.1"
@@ -113,7 +124,7 @@ dependencies = [
113
124
  [[package]]
114
125
  name = "btls"
115
126
  version = "0.5.6"
116
- source = "git+https://github.com/0x676e67/btls?rev=de7ab84fdb58641a2bdfdf9d8ebd7db1dcf4b29b#de7ab84fdb58641a2bdfdf9d8ebd7db1dcf4b29b"
127
+ source = "git+https://github.com/0x676e67/btls?rev=5ec1c113a03626a5877b34dd6d2ea8d440897a91#5ec1c113a03626a5877b34dd6d2ea8d440897a91"
117
128
  dependencies = [
118
129
  "bitflags",
119
130
  "btls-sys",
@@ -125,9 +136,9 @@ dependencies = [
125
136
  [[package]]
126
137
  name = "btls-sys"
127
138
  version = "0.5.6"
128
- source = "git+https://github.com/0x676e67/btls?rev=de7ab84fdb58641a2bdfdf9d8ebd7db1dcf4b29b#de7ab84fdb58641a2bdfdf9d8ebd7db1dcf4b29b"
139
+ source = "git+https://github.com/0x676e67/btls?rev=5ec1c113a03626a5877b34dd6d2ea8d440897a91#5ec1c113a03626a5877b34dd6d2ea8d440897a91"
129
140
  dependencies = [
130
- "bindgen",
141
+ "bindgen 0.73.2",
131
142
  "cmake",
132
143
  "fs_extra",
133
144
  "fslock",
@@ -433,8 +444,6 @@ version = "0.17.1"
433
444
  source = "registry+https://github.com/rust-lang/crates.io-index"
434
445
  checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
435
446
  dependencies = [
436
- "allocator-api2",
437
- "equivalent",
438
447
  "foldhash",
439
448
  ]
440
449
 
@@ -474,7 +483,7 @@ dependencies = [
474
483
  [[package]]
475
484
  name = "http2"
476
485
  version = "0.5.20"
477
- source = "git+https://github.com/0x676e67/http2?rev=b413a92b2e1fe7e2ea1b7be78e75b872386fdfa0#b413a92b2e1fe7e2ea1b7be78e75b872386fdfa0"
486
+ source = "git+https://github.com/0x676e67/http2?rev=29b3bdfc7560d6f84119c103311afa147488b6f0#29b3bdfc7560d6f84119c103311afa147488b6f0"
478
487
  dependencies = [
479
488
  "atomic-waker",
480
489
  "bytes",
@@ -681,9 +690,9 @@ dependencies = [
681
690
 
682
691
  [[package]]
683
692
  name = "lru"
684
- version = "0.18.2"
693
+ version = "0.19.0"
685
694
  source = "registry+https://github.com/rust-lang/crates.io-index"
686
- checksum = "5d2f2f9b4ba7e6b24d95e7e899329d35be83bcded72c8540cdd5368932d1d90a"
695
+ checksum = "4a9f71e3591c7ec44d3e563e87bf14ddc2bada8519dca046e5b0e560cd004e2d"
687
696
  dependencies = [
688
697
  "hashbrown",
689
698
  ]
@@ -873,7 +882,7 @@ version = "0.9.128"
873
882
  source = "registry+https://github.com/rust-lang/crates.io-index"
874
883
  checksum = "ce04b2c55eff3a21aaa623fcc655d94373238e72cac6b3e1a3641ff31649f99a"
875
884
  dependencies = [
876
- "bindgen",
885
+ "bindgen 0.72.1",
877
886
  "lazy_static",
878
887
  "proc-macro2",
879
888
  "quote",
@@ -1218,10 +1227,10 @@ dependencies = [
1218
1227
  [[package]]
1219
1228
  name = "tokio-btls"
1220
1229
  version = "0.5.6"
1221
- source = "registry+https://github.com/rust-lang/crates.io-index"
1222
- checksum = "2e1fd638ec35427faf3b8f412e0fdd6fae76591d79dba40f38fa667d22bc44dd"
1230
+ source = "git+https://github.com/0x676e67/btls?rev=5ec1c113a03626a5877b34dd6d2ea8d440897a91#5ec1c113a03626a5877b34dd6d2ea8d440897a91"
1223
1231
  dependencies = [
1224
1232
  "btls",
1233
+ "btls-sys",
1225
1234
  "tokio",
1226
1235
  ]
1227
1236
 
@@ -1421,7 +1430,7 @@ dependencies = [
1421
1430
  [[package]]
1422
1431
  name = "wreq"
1423
1432
  version = "0.16.1"
1424
- source = "git+https://github.com/0x676e67/wreq?rev=abd421d16dd48b3c2d7fb812f185eec3c6ec3132#abd421d16dd48b3c2d7fb812f185eec3c6ec3132"
1433
+ source = "git+https://github.com/0x676e67/wreq?rev=74fc1469b5c54b3fb93037e48f136b569d0fe418#74fc1469b5c54b3fb93037e48f136b569d0fe418"
1425
1434
  dependencies = [
1426
1435
  "btls",
1427
1436
  "btls-sys",
@@ -1490,7 +1499,7 @@ dependencies = [
1490
1499
 
1491
1500
  [[package]]
1492
1501
  name = "wreq-ruby"
1493
- version = "1.3.0"
1502
+ version = "1.3.2"
1494
1503
  dependencies = [
1495
1504
  "arc-swap",
1496
1505
  "bytes",
data/Cargo.toml CHANGED
@@ -5,7 +5,7 @@ authors = ["SearchApi <support@searchapi.io>"]
5
5
  homepage = "https://github.com/SearchApi/wreq-ruby"
6
6
  repository = "https://github.com/SearchApi/wreq-ruby"
7
7
  edition = "2024"
8
- version = "1.3.0"
8
+ version = "1.3.2"
9
9
  rust-version = "1.98"
10
10
 
11
11
  [lib]
@@ -17,7 +17,10 @@ name = "wreq_ruby"
17
17
  magnus = { version = "0.8.2", features = ["bytes"] }
18
18
  rb-sys = { version = "0.9.128", default-features = false }
19
19
  tokio = { version = "1.53.1", features = ["full"] }
20
- wreq = { version = "0.16.1", features = [
20
+ # Keep the existing trust store independent of wreq's default feature selection.
21
+ wreq = { version = "0.16.1", default-features = false, features = [
22
+ "tokio-rt",
23
+ "chromium-roots",
21
24
  "query",
22
25
  "form",
23
26
  "json",
@@ -64,8 +67,9 @@ opt-level = 3
64
67
  strip = true
65
68
 
66
69
  [patch.crates-io]
67
- http2 = { git = "https://github.com/0x676e67/http2", rev = "b413a92b2e1fe7e2ea1b7be78e75b872386fdfa0" }
68
- btls = { git = "https://github.com/0x676e67/btls", rev = "de7ab84fdb58641a2bdfdf9d8ebd7db1dcf4b29b" }
69
- btls-sys = { git = "https://github.com/0x676e67/btls", rev = "de7ab84fdb58641a2bdfdf9d8ebd7db1dcf4b29b" }
70
- wreq = { git = "https://github.com/0x676e67/wreq", rev = "abd421d16dd48b3c2d7fb812f185eec3c6ec3132" }
70
+ http2 = { git = "https://github.com/0x676e67/http2", rev = "29b3bdfc7560d6f84119c103311afa147488b6f0" }
71
+ btls = { git = "https://github.com/0x676e67/btls", rev = "5ec1c113a03626a5877b34dd6d2ea8d440897a91" }
72
+ btls-sys = { git = "https://github.com/0x676e67/btls", rev = "5ec1c113a03626a5877b34dd6d2ea8d440897a91" }
73
+ tokio-btls = { git = "https://github.com/0x676e67/btls", rev = "5ec1c113a03626a5877b34dd6d2ea8d440897a91" }
74
+ wreq = { git = "https://github.com/0x676e67/wreq", rev = "74fc1469b5c54b3fb93037e48f136b569d0fe418" }
71
75
  wreq-util = { path = "crates/wreq-util" }
data/README.md CHANGED
@@ -91,7 +91,7 @@ Most browser device models share identical TLS and HTTP/2 configurations, differ
91
91
 
92
92
  | **Browser** | **Versions** |
93
93
  | ----------- | ------------ |
94
- | **Chrome** | `Chrome100`, `Chrome101`, `Chrome104`, `Chrome105`, `Chrome106`, `Chrome107`, `Chrome108`, `Chrome109`, `Chrome110`, `Chrome114`, `Chrome116`, `Chrome117`, `Chrome118`, `Chrome119`, `Chrome120`, `Chrome123`, `Chrome124`, `Chrome126`, `Chrome127`, `Chrome128`, `Chrome129`, `Chrome130`, `Chrome131`, `Chrome132`, `Chrome133`, `Chrome134`, `Chrome135`, `Chrome136`, `Chrome137`, `Chrome138`, `Chrome139`, `Chrome140`, `Chrome141`, `Chrome142`, `Chrome143`, `Chrome144`, `Chrome145`, `Chrome146`, `Chrome147`, `Chrome148`, `Chrome149`, `Chrome150`, `Chrome151`, `Chrome152`, `Chrome153`, `Chrome154` |
94
+ | **Chrome** | `Chrome100`, `Chrome101`, `Chrome104`, `Chrome105`, `Chrome106`, `Chrome107`, `Chrome108`, `Chrome109`, `Chrome110`, `Chrome114`, `Chrome116`, `Chrome117`, `Chrome118`, `Chrome119`, `Chrome120`, `Chrome123`, `Chrome124`, `Chrome126`, `Chrome127`, `Chrome128`, `Chrome129`, `Chrome130`, `Chrome131`, `Chrome132`, `Chrome133`, `Chrome134`, `Chrome135`, `Chrome136`, `Chrome137`, `Chrome138`, `Chrome139`, `Chrome140`, `Chrome141`, `Chrome142`, `Chrome143`, `Chrome144`, `Chrome145`, `Chrome146`, `Chrome147`, `Chrome148`, `Chrome149`, `Chrome150`, `Chrome151`, `Chrome152`, `Chrome153`, `Chrome154`, `Chrome155`, `Chrome156` |
95
95
  | **Edge** | `Edge101`, `Edge122`, `Edge127`, `Edge131`, `Edge134`, `Edge135`, `Edge136`, `Edge137`, `Edge138`, `Edge139`, `Edge140`, `Edge141`, `Edge142`, `Edge143`, `Edge144`, `Edge145`, `Edge146`, `Edge147`, `Edge148` |
96
96
  | **Firefox** | `Firefox109`, `Firefox117`, `Firefox128`, `Firefox133`, `Firefox135`, `FirefoxPrivate135`, `FirefoxAndroid135`, `Firefox136`, `FirefoxPrivate136`, `Firefox139`, `Firefox142`, `Firefox143`, `Firefox144`, `Firefox145`, `Firefox146`, `Firefox147`, `Firefox148`, `Firefox149`, `Firefox150`, `Firefox151`, `Firefox152` |
97
97
  | **Safari** | `Safari15_3`, `Safari15_5`, `Safari15_6_1`, `Safari16`, `Safari16_5`, `Safari17_0`, `Safari17_2_1`, `Safari17_4_1`, `Safari17_5`, `Safari17_6`, `Safari18`, `Safari18_2`, `Safari18_3`, `Safari18_3_1`, `Safari18_5`, `Safari26`, `Safari26_1`, `Safari26_2`, `SafariIos16_5`, `SafariIos17_2`, `SafariIos17_4_1`, `SafariIos18_1_1`, `SafariIos26`, `SafariIos26_2`, `SafariIPad18`, `SafariIPad26`, `SafariIpad26_2` |
@@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
13
13
  - *(emulate)* Add Chrome 152 profile.
14
14
  - *(emulate)* Add Chrome 153 profile.
15
15
  - *(emulate)* Add Chrome 154 profile.
16
+ - *(emulate)* Add Chrome 155 profile, including the JPEG XL navigation Accept header.
17
+ - *(emulate)* Add Chrome 156 profile.
16
18
  - *(emulate)* Add Firefox 152 profile.
17
19
 
18
20
  ### Fixed
@@ -17,7 +17,7 @@ rustdoc-args = ["--cfg", "docsrs"]
17
17
  targets = ["x86_64-unknown-linux-gnu"]
18
18
 
19
19
  [features]
20
- default = ["emulation"]
20
+ default = ["emulation", "tokio-rt"]
21
21
 
22
22
  tokio-rt = ["wreq/tokio-rt"]
23
23
  compio-rt = ["wreq/compio-rt"]
@@ -54,6 +54,7 @@ zstd = { version = "0.13.3", optional = true }
54
54
 
55
55
  [dev-dependencies]
56
56
  wreq = "0.16.1"
57
+ serde_json = "1.0.151"
57
58
  tokio = { version = "1.48.0", features = ["full"] }
58
59
  hyper = { version = "1.10.1", default-features = false, features = [
59
60
  "http1",
@@ -73,6 +73,20 @@ pub fn header_initializer_with_zstd_priority(
73
73
  headers
74
74
  }
75
75
 
76
+ pub fn header_initializer_chrome155(
77
+ sec_ch_ua: &'static str,
78
+ ua: &'static str,
79
+ emulation_os: Platform,
80
+ ) -> HeaderMap {
81
+ let mut headers = header_initializer_with_zstd_priority(sec_ch_ua, ua, emulation_os);
82
+ // Chrome 155 enables JPEG XL in Blink; the iOS profile keeps its WebKit headers.
83
+ // https://chromium.googlesource.com/chromium/src/+/cfaadc5a132d78e1828635aa8405a499f3e14864/content/common/content_constants_internal.h
84
+ if !matches!(emulation_os, Platform::IOS) {
85
+ headers.insert(ACCEPT, HeaderValue::from_static("text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"));
86
+ }
87
+ headers
88
+ }
89
+
76
90
  pub fn header_initializer_chrome152(
77
91
  sec_ch_ua: &'static str,
78
92
  ua: &'static str,
@@ -71,9 +71,6 @@ pub const CURVES_3: &str = join!(":", "X25519MLKEM768", "X25519", "P-256", "P-38
71
71
 
72
72
  pub const CIPHER_LIST: &str = join!(
73
73
  ":",
74
- "TLS_AES_128_GCM_SHA256",
75
- "TLS_AES_256_GCM_SHA384",
76
- "TLS_CHACHA20_POLY1305_SHA256",
77
74
  "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
78
75
  "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
79
76
  "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
@@ -88,6 +85,12 @@ pub const CIPHER_LIST: &str = join!(
88
85
  "TLS_RSA_WITH_AES_256_CBC_SHA"
89
86
  );
90
87
 
88
+ pub const TLS13_CIPHER_LIST: &[Tls13Cipher] = &[
89
+ Tls13Cipher::AES_128_GCM_SHA256,
90
+ Tls13Cipher::AES_256_GCM_SHA384,
91
+ Tls13Cipher::CHACHA20_POLY1305_SHA256,
92
+ ];
93
+
91
94
  pub const SIGALGS_LIST: &str = join!(
92
95
  ":",
93
96
  "ecdsa_secp256r1_sha256",
@@ -200,14 +203,17 @@ impl From<ChromeTlsConfig> for TlsOptions {
200
203
  .curves_list(val.curves)
201
204
  .sigalgs_list(val.sigalgs_list)
202
205
  .cipher_list(val.cipher_list)
206
+ .tls13_cipher_list(TLS13_CIPHER_LIST)
203
207
  .min_tls_version(TlsVersion::TLS_1_2)
204
208
  .max_tls_version(TlsVersion::TLS_1_3)
205
209
  .permute_extensions(val.permute_extensions)
206
210
  .pre_shared_key(val.pre_shared_key)
207
- .enable_ech_grease(val.enable_ech_grease)
211
+ .ech_grease(
212
+ val.enable_ech_grease
213
+ .then_some(EchGrease::Aead(EchGreaseAead::AES_128_GCM)),
214
+ )
208
215
  .alps_protocols([val.alps_protos])
209
216
  .alps_use_new_codepoint(val.alps_use_new_codepoint)
210
- .aes_hw_override(true)
211
217
  .certificate_compressors(CERTIFICATE_COMPRESSORS);
212
218
  let builder = if let Some(trust_anchors) = val.trust_anchors {
213
219
  builder.trust_anchors(trust_anchors)
@@ -234,6 +240,8 @@ mod tests {
234
240
  crate::Profile::Chrome152,
235
241
  crate::Profile::Chrome153,
236
242
  crate::Profile::Chrome154,
243
+ crate::Profile::Chrome155,
244
+ crate::Profile::Chrome156,
237
245
  ] {
238
246
  let native = profile.into_emulation();
239
247
  let cloned = native.clone();
@@ -243,7 +251,10 @@ mod tests {
243
251
  let decoded = decode_ids(&ids);
244
252
  let mut expected = chromium_roots::trust_anchor_ids();
245
253
  expected.sort_unstable();
246
- if profile == crate::Profile::Chrome154 {
254
+ if matches!(
255
+ profile,
256
+ crate::Profile::Chrome154 | crate::Profile::Chrome155 | crate::Profile::Chrome156
257
+ ) {
247
258
  assert_eq!(decoded, expected);
248
259
  }
249
260
  let mut actual = decoded;
@@ -1963,6 +1963,77 @@ mod_generator!(
1963
1963
  ]
1964
1964
  );
1965
1965
 
1966
+ // Chrome 155 retains Chrome 154's TLS/HTTP2 configuration. Its UA-CH permutation
1967
+ // and GREASE brand are seeded by major version 155.
1968
+ // https://chromium.googlesource.com/chromium/src/+/cfaadc5a132d78e1828635aa8405a499f3e14864/components/embedder_support/user_agent_utils.cc
1969
+ mod_generator!(
1970
+ v155,
1971
+ v154::build_emulation,
1972
+ header_initializer_chrome155,
1973
+ [
1974
+ (
1975
+ MacOS,
1976
+ r#""Google Chrome";v="155", "Chromium";v="155", "Not(A:Brand";v="24""#,
1977
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/155.0.0.0 Safari/537.36"
1978
+ ),
1979
+ (
1980
+ Linux,
1981
+ r#""Google Chrome";v="155", "Chromium";v="155", "Not(A:Brand";v="24""#,
1982
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/155.0.0.0 Safari/537.36"
1983
+ ),
1984
+ (
1985
+ Android,
1986
+ r#""Google Chrome";v="155", "Chromium";v="155", "Not(A:Brand";v="24""#,
1987
+ "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/155.0.0.0 Mobile Safari/537.36"
1988
+ ),
1989
+ (
1990
+ Windows,
1991
+ r#""Google Chrome";v="155", "Chromium";v="155", "Not(A:Brand";v="24""#,
1992
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/155.0.0.0 Safari/537.36"
1993
+ ),
1994
+ (
1995
+ IOS,
1996
+ r#""Google Chrome";v="155", "Chromium";v="155", "Not(A:Brand";v="24""#,
1997
+ "Mozilla/5.0 (iPhone; CPU iPhone OS 18_7_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/155.0.8059.37 Mobile/15E148 Safari/604.1"
1998
+ )
1999
+ ]
2000
+ );
2001
+
2002
+ // Chrome 156 retains Chrome 155's TLS/HTTP2 and Accept configuration.
2003
+ // https://chromium.googlesource.com/chromium/src/+/29eb03535d5f2f4f899b95f22a92413ffde5284e/components/embedder_support/user_agent_utils.cc
2004
+ mod_generator!(
2005
+ v156,
2006
+ v154::build_emulation,
2007
+ header_initializer_chrome155,
2008
+ [
2009
+ (
2010
+ MacOS,
2011
+ r#""Not:A-Brand";v="8", "Chromium";v="156", "Google Chrome";v="156""#,
2012
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/156.0.0.0 Safari/537.36"
2013
+ ),
2014
+ (
2015
+ Linux,
2016
+ r#""Not:A-Brand";v="8", "Chromium";v="156", "Google Chrome";v="156""#,
2017
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/156.0.0.0 Safari/537.36"
2018
+ ),
2019
+ (
2020
+ Android,
2021
+ r#""Not:A-Brand";v="8", "Chromium";v="156", "Google Chrome";v="156""#,
2022
+ "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/156.0.0.0 Mobile Safari/537.36"
2023
+ ),
2024
+ (
2025
+ Windows,
2026
+ r#""Not:A-Brand";v="8", "Chromium";v="156", "Google Chrome";v="156""#,
2027
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/156.0.0.0 Safari/537.36"
2028
+ ),
2029
+ (
2030
+ IOS,
2031
+ r#""Not:A-Brand";v="8", "Chromium";v="156", "Google Chrome";v="156""#,
2032
+ "Mozilla/5.0 (iPhone; CPU iPhone OS 18_7_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/156.0.8078.54 Mobile/15E148 Safari/604.1"
2033
+ )
2034
+ ]
2035
+ );
2036
+
1966
2037
  mod_generator!(
1967
2038
  edge143,
1968
2039
  v132::build_emulation,
@@ -86,9 +86,6 @@ pub const KEY_SHARES_2: &[KeyShare] =
86
86
 
87
87
  pub const CIPHER_LIST_1: &str = join!(
88
88
  ":",
89
- "TLS_AES_128_GCM_SHA256",
90
- "TLS_CHACHA20_POLY1305_SHA256",
91
- "TLS_AES_256_GCM_SHA384",
92
89
  "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
93
90
  "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
94
91
  "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
@@ -107,9 +104,6 @@ pub const CIPHER_LIST_1: &str = join!(
107
104
 
108
105
  pub const CIPHER_LIST_2: &str = join!(
109
106
  ":",
110
- "TLS_AES_128_GCM_SHA256",
111
- "TLS_CHACHA20_POLY1305_SHA256",
112
- "TLS_AES_256_GCM_SHA384",
113
107
  "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
114
108
  "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
115
109
  "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
@@ -126,9 +120,6 @@ pub const CIPHER_LIST_2: &str = join!(
126
120
 
127
121
  pub const CIPHER_LIST_3: &str = join!(
128
122
  ":",
129
- "TLS_AES_128_GCM_SHA256",
130
- "TLS_CHACHA20_POLY1305_SHA256",
131
- "TLS_AES_256_GCM_SHA384",
132
123
  "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
133
124
  "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
134
125
  "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
@@ -159,6 +150,12 @@ pub const SIGALGS_LIST: &str = join!(
159
150
  "rsa_pkcs1_sha1"
160
151
  );
161
152
 
153
+ pub const TLS13_CIPHER_LIST: &[Tls13Cipher] = &[
154
+ Tls13Cipher::AES_128_GCM_SHA256,
155
+ Tls13Cipher::CHACHA20_POLY1305_SHA256,
156
+ Tls13Cipher::AES_256_GCM_SHA384,
157
+ ];
158
+
162
159
  pub const CERTIFICATE_COMPRESSORS: &[&'static dyn CertificateCompressor] =
163
160
  &[&ZlibCompressor, &BrotliCompressor, &ZstdCompressor];
164
161
 
@@ -243,11 +240,12 @@ impl From<FirefoxTlsConfig> for TlsOptions {
243
240
  .curves_list(val.curves_list)
244
241
  .sigalgs_list(val.sigalgs_list)
245
242
  .cipher_list(val.cipher_list)
243
+ .tls13_cipher_list(TLS13_CIPHER_LIST)
246
244
  .session_ticket(val.session_ticket)
247
245
  .delegated_credentials(val.delegated_credentials)
248
246
  .record_size_limit(val.record_size_limit)
249
247
  .enable_ocsp_stapling(true)
250
- .enable_ech_grease(val.enable_ech_grease)
248
+ .ech_grease(val.enable_ech_grease.then_some(EchGrease::NssPre3127))
251
249
  .enable_signed_cert_timestamps(val.enable_signed_cert_timestamps)
252
250
  .alpn_protocols([AlpnProtocol::HTTP2, AlpnProtocol::HTTP1])
253
251
  .min_tls_version(TlsVersion::TLS_1_2)
@@ -255,10 +253,7 @@ impl From<FirefoxTlsConfig> for TlsOptions {
255
253
  .pre_shared_key(val.pre_shared_key)
256
254
  .psk_skip_session_ticket(val.psk_skip_session_tickets)
257
255
  .psk_dhe_ke(val.psk_dhe_ke)
258
- .preserve_tls13_cipher_list(true)
259
- .extension_permutation(val.extension_permutation)
260
- .aes_hw_override(true)
261
- .random_aes_hw_override(true);
256
+ .extension_permutation(val.extension_permutation);
262
257
 
263
258
  if let Some(key_shares) = val.key_shares {
264
259
  builder = builder.key_shares(key_shares)
@@ -17,9 +17,6 @@ const SIGALGS_LIST: &str = join!(
17
17
 
18
18
  const CIPHER_LIST: &str = join!(
19
19
  ":",
20
- "TLS_AES_128_GCM_SHA256",
21
- "TLS_AES_256_GCM_SHA384",
22
- "TLS_CHACHA20_POLY1305_SHA256",
23
20
  "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
24
21
  "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
25
22
  "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
@@ -35,6 +32,12 @@ const CIPHER_LIST: &str = join!(
35
32
  "TLS_RSA_WITH_3DES_EDE_CBC_SHA"
36
33
  );
37
34
 
35
+ const TLS13_CIPHER_LIST: &[Tls13Cipher] = &[
36
+ Tls13Cipher::AES_128_GCM_SHA256,
37
+ Tls13Cipher::AES_256_GCM_SHA384,
38
+ Tls13Cipher::CHACHA20_POLY1305_SHA256,
39
+ ];
40
+
38
41
  #[derive(TypedBuilder)]
39
42
  struct OkHttpTlsConfig {
40
43
  #[builder(default = CURVES)]
@@ -53,9 +56,9 @@ impl From<OkHttpTlsConfig> for TlsOptions {
53
56
  .curves_list(val.curves)
54
57
  .sigalgs_list(val.sigalgs_list)
55
58
  .cipher_list(val.cipher_list)
59
+ .tls13_cipher_list(TLS13_CIPHER_LIST)
56
60
  .min_tls_version(TlsVersion::TLS_1_2)
57
61
  .max_tls_version(TlsVersion::TLS_1_3)
58
- .aes_hw_override(true)
59
62
  .build()
60
63
  }
61
64
  }
@@ -175,11 +178,6 @@ mod_generator!(
175
178
  okhttp3_13,
176
179
  join!(
177
180
  ":",
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
181
  "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
184
182
  "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
185
183
  "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
@@ -213,9 +211,6 @@ mod_generator!(
213
211
  okhttp4_9,
214
212
  join!(
215
213
  ":",
216
- "TLS_AES_128_GCM_SHA256",
217
- "TLS_AES_256_GCM_SHA384",
218
- "TLS_CHACHA20_POLY1305_SHA256",
219
214
  "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
220
215
  "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
221
216
  "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
@@ -16,9 +16,6 @@ pub const CURVES: &str = join!(":", "X25519MLKEM768", "X25519", "P-256", "P-384"
16
16
 
17
17
  pub const CIPHER_LIST: &str = join!(
18
18
  ":",
19
- "TLS_AES_128_GCM_SHA256",
20
- "TLS_AES_256_GCM_SHA384",
21
- "TLS_CHACHA20_POLY1305_SHA256",
22
19
  "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
23
20
  "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
24
21
  "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
@@ -33,6 +30,12 @@ pub const CIPHER_LIST: &str = join!(
33
30
  "TLS_RSA_WITH_AES_256_CBC_SHA"
34
31
  );
35
32
 
33
+ pub const TLS13_CIPHER_LIST: &[Tls13Cipher] = &[
34
+ Tls13Cipher::AES_128_GCM_SHA256,
35
+ Tls13Cipher::AES_256_GCM_SHA384,
36
+ Tls13Cipher::CHACHA20_POLY1305_SHA256,
37
+ ];
38
+
36
39
  pub const SIGALGS_LIST: &str = join!(
37
40
  ":",
38
41
  "ecdsa_secp256r1_sha256",
@@ -83,14 +86,17 @@ impl From<OperaTlsConfig> for TlsOptions {
83
86
  .curves_list(val.curves)
84
87
  .sigalgs_list(val.sigalgs_list)
85
88
  .cipher_list(val.cipher_list)
89
+ .tls13_cipher_list(TLS13_CIPHER_LIST)
86
90
  .min_tls_version(TlsVersion::TLS_1_2)
87
91
  .max_tls_version(TlsVersion::TLS_1_3)
88
92
  .permute_extensions(val.permute_extensions)
89
93
  .pre_shared_key(val.pre_shared_key)
90
- .enable_ech_grease(val.enable_ech_grease)
94
+ .ech_grease(
95
+ val.enable_ech_grease
96
+ .then_some(EchGrease::Aead(EchGreaseAead::AES_128_GCM)),
97
+ )
91
98
  .alps_protocols([val.alps_protos])
92
99
  .alps_use_new_codepoint(val.alps_use_new_codepoint)
93
- .aes_hw_override(true)
94
100
  .certificate_compressors(CERTIFICATE_COMPRESSORS)
95
101
  .build()
96
102
  }
@@ -19,7 +19,7 @@ macro_rules! tls_options {
19
19
  .curves($curves)
20
20
  .cipher_list($cipher_list)
21
21
  .sigalgs_list($sigalgs_list)
22
- .preserve_tls13_cipher_list(true)
22
+ .tls13_cipher_list(TLS13_CIPHER_LIST)
23
23
  .min_tls_version(wreq::tls::TlsVersion::TLS_1_2)
24
24
  .max_tls_version(wreq::tls::TlsVersion::TLS_1_3)
25
25
  .build()
@@ -33,9 +33,6 @@ pub const CURVES_2: &str = join!(":", "X25519MLKEM768", "X25519", "P-256", "P-38
33
33
 
34
34
  pub const CIPHER_LIST_1: &str = join!(
35
35
  ":",
36
- "TLS_AES_128_GCM_SHA256",
37
- "TLS_AES_256_GCM_SHA384",
38
- "TLS_CHACHA20_POLY1305_SHA256",
39
36
  "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
40
37
  "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
41
38
  "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
@@ -62,9 +59,6 @@ pub const CIPHER_LIST_1: &str = join!(
62
59
  );
63
60
  pub const CIPHER_LIST_2: &str = join!(
64
61
  ":",
65
- "TLS_AES_128_GCM_SHA256",
66
- "TLS_AES_256_GCM_SHA384",
67
- "TLS_CHACHA20_POLY1305_SHA256",
68
62
  "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
69
63
  "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
70
64
  "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
@@ -85,9 +79,6 @@ pub const CIPHER_LIST_2: &str = join!(
85
79
  );
86
80
  pub const CIPHER_LIST_3: &str = join!(
87
81
  ":",
88
- "TLS_AES_256_GCM_SHA384",
89
- "TLS_CHACHA20_POLY1305_SHA256",
90
- "TLS_AES_128_GCM_SHA256",
91
82
  "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
92
83
  "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
93
84
  "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
@@ -107,6 +98,12 @@ pub const CIPHER_LIST_3: &str = join!(
107
98
  "TLS_RSA_WITH_3DES_EDE_CBC_SHA"
108
99
  );
109
100
 
101
+ pub const TLS13_CIPHER_LIST: &[Tls13Cipher] = &[
102
+ Tls13Cipher::AES_256_GCM_SHA384,
103
+ Tls13Cipher::CHACHA20_POLY1305_SHA256,
104
+ Tls13Cipher::AES_128_GCM_SHA256,
105
+ ];
106
+
110
107
  pub const SIGALGS_LIST_1: &str = join!(
111
108
  ":",
112
109
  "ecdsa_secp256r1_sha256",
@@ -155,23 +152,25 @@ pub struct SafariTlsConfig {
155
152
  cipher_list: &'static str,
156
153
 
157
154
  #[builder(default, setter(strip_option))]
158
- preserve_tls13_cipher_list: Option<bool>,
155
+ tls13_cipher_list: Option<&'static [Tls13Cipher]>,
159
156
  }
160
157
 
161
158
  impl From<SafariTlsConfig> for TlsOptions {
162
159
  fn from(val: SafariTlsConfig) -> Self {
163
- TlsOptions::builder()
160
+ let mut builder = TlsOptions::builder()
164
161
  .session_ticket(false)
165
162
  .grease_enabled(true)
166
163
  .enable_ocsp_stapling(true)
167
164
  .enable_signed_cert_timestamps(true)
168
- .preserve_tls13_cipher_list(val.preserve_tls13_cipher_list)
169
165
  .curves_list(val.curves)
170
166
  .sigalgs_list(val.sigalgs_list)
171
167
  .cipher_list(val.cipher_list)
172
168
  .min_tls_version(val.min_tls_version)
173
169
  .max_tls_version(val.max_tls_version)
174
- .certificate_compressors(CERTIFICATE_COMPRESSORS)
175
- .build()
170
+ .certificate_compressors(CERTIFICATE_COMPRESSORS);
171
+ if let Some(ciphers) = val.tls13_cipher_list {
172
+ builder = builder.tls13_cipher_list(ciphers);
173
+ }
174
+ builder.build()
176
175
  }
177
176
  }
@@ -17,8 +17,8 @@ use wreq::{
17
17
  StreamDependency, StreamId,
18
18
  },
19
19
  tls::{
20
- AlpnProtocol, AlpsProtocol, ExtensionType, KeyShare, TlsOptions, TlsVersion,
21
- compress::CertificateCompressor,
20
+ AlpnProtocol, AlpsProtocol, EchGrease, EchGreaseAead, ExtensionType, KeyShare, Tls13Cipher,
21
+ TlsOptions, TlsVersion, compress::CertificateCompressor,
22
22
  },
23
23
  };
24
24
 
@@ -65,6 +65,8 @@ define_enum!(
65
65
  Chrome152 => ("chrome_152", v152::emulation),
66
66
  Chrome153 => ("chrome_153", v153::emulation),
67
67
  Chrome154 => ("chrome_154", v154::emulation),
68
+ Chrome155 => ("chrome_155", v155::emulation),
69
+ Chrome156 => ("chrome_156", v156::emulation),
68
70
 
69
71
  // Edge versions
70
72
  Edge101 => ("edge_101", edge101::emulation),
@@ -220,7 +222,7 @@ impl Platform {
220
222
  /// Conversion through [`wreq::IntoEmulation`] creates a native configuration,
221
223
  /// including a randomized Trust Anchor ID order for Chrome 152/153 profiles.
222
224
  /// Client-level emulation retains that order for subsequent connections.
223
- /// Chrome 154 sorts the IDs by their raw bytes instead.
225
+ /// Chrome 154–156 sort the IDs by their raw bytes instead.
224
226
  #[derive(Default, Clone, TypedBuilder)]
225
227
  pub struct Emulation {
226
228
  /// Whether to change the profile (browser/okhttp) information.
@@ -305,3 +305,23 @@ test_emulation!(
305
305
  ],
306
306
  "52d84b11737d980aef856699f885ca86"
307
307
  );
308
+
309
+ test_emulation!(
310
+ test_chrome155,
311
+ Emulation::Chrome155,
312
+ [
313
+ "t13d1517h2_8daaf6152771_cb7bf5808d99",
314
+ "t13d1518h2_8daaf6152771_e2d80978ab2e"
315
+ ],
316
+ "52d84b11737d980aef856699f885ca86"
317
+ );
318
+
319
+ test_emulation!(
320
+ test_chrome156,
321
+ Emulation::Chrome156,
322
+ [
323
+ "t13d1517h2_8daaf6152771_cb7bf5808d99",
324
+ "t13d1518h2_8daaf6152771_e2d80978ab2e"
325
+ ],
326
+ "52d84b11737d980aef856699f885ca86"
327
+ );
@@ -147,5 +147,5 @@ test_emulation!(
147
147
  test_safari_26_1,
148
148
  Emulation::Safari26_1,
149
149
  ["t13d2014h2_a09f3c656075_e42f34c56612"],
150
- "773906b0efdefa24a7f2b8eb6985bf37"
150
+ "c52879e43202aeb92740be6e8c86ea96"
151
151
  );
@@ -36,18 +36,21 @@ macro_rules! test_emulation {
36
36
 
37
37
  assert_eq!(resp.status(), wreq::StatusCode::OK);
38
38
  let content = resp.text().await.unwrap();
39
-
40
- let conditional = $ja4.iter().any(|&ja4| content.contains(ja4));
41
- if !conditional {
42
- println!("{}", content);
43
- }
44
- assert!(conditional);
45
-
46
- let conditional = content.contains($akamai_hash);
47
- if !conditional {
48
- println!("{}", content);
49
- }
50
- assert!(conditional);
39
+ let fingerprint: serde_json::Value = serde_json::from_str(&content)
40
+ .unwrap_or_else(|error| panic!("invalid fingerprint JSON: {error}\n{content}"));
41
+
42
+ let actual_ja4 = fingerprint["ja4"].as_str();
43
+ assert!(
44
+ actual_ja4.is_some_and(|value| $ja4.contains(&value)),
45
+ "JA4 fingerprint mismatch: expected {:?}, got {actual_ja4:?}\n{content}",
46
+ $ja4
47
+ );
48
+
49
+ assert_eq!(
50
+ fingerprint["akamai_hash"].as_str(),
51
+ Some($akamai_hash),
52
+ "HTTP/2 fingerprint mismatch:\n{content}"
53
+ );
51
54
 
52
55
  tokio::time::sleep(std::time::Duration::from_millis(1000)).await;
53
56
  }
data/lib/wreq.rb CHANGED
@@ -76,7 +76,7 @@ unless defined?(Wreq)
76
76
  # @param deflate [Boolean, nil] Enable deflate compression
77
77
  # @param zstd [Boolean, nil] Enable Zstandard compression
78
78
  # @param timeout [Integer, nil] Total request timeout (seconds)
79
- # @param read_timeout [Integer, nil] Per-chunk read timeout (seconds)
79
+ # @param read_timeout [Integer, nil] Timeout for headers or each body chunk (seconds)
80
80
  # @param proxy [String, nil] Proxy server URI
81
81
  # @param local_address [String, nil] Bind the client's local source IP address (IPv4/IPv6). Useful on multi-homed hosts to originate connections from a specific address or enforce source routing. Examples: "192.168.1.10", "10.0.0.5", "2001:db8::1". The address must exist on the host and be routable or the connection may fail.
82
82
  # @param interface [String, nil] Bind to an interface on supported platforms; unsupported platforms raise ArgumentError.
@@ -110,7 +110,7 @@ unless defined?(Wreq)
110
110
  # @param deflate [Boolean, nil] Enable deflate compression
111
111
  # @param zstd [Boolean, nil] Enable Zstandard compression
112
112
  # @param timeout [Integer, nil] Total request timeout (seconds)
113
- # @param read_timeout [Integer, nil] Per-chunk read timeout (seconds)
113
+ # @param read_timeout [Integer, nil] Timeout for headers or each body chunk (seconds)
114
114
  # @param proxy [String, nil] Proxy server URI
115
115
  # @param local_address [String, nil] Bind the client's local source IP address (IPv4/IPv6). Useful on multi-homed hosts to originate connections from a specific address or enforce source routing. Examples: "192.168.1.10", "10.0.0.5", "2001:db8::1". The address must exist on the host and be routable or the connection may fail.
116
116
  # @param interface [String, nil] Bind to an interface on supported platforms; unsupported platforms raise ArgumentError.
@@ -144,7 +144,7 @@ unless defined?(Wreq)
144
144
  # @param deflate [Boolean, nil] Enable deflate compression
145
145
  # @param zstd [Boolean, nil] Enable Zstandard compression
146
146
  # @param timeout [Integer, nil] Total request timeout (seconds)
147
- # @param read_timeout [Integer, nil] Per-chunk read timeout (seconds)
147
+ # @param read_timeout [Integer, nil] Timeout for headers or each body chunk (seconds)
148
148
  # @param proxy [String, nil] Proxy server URI
149
149
  # @param local_address [String, nil] Bind the client's local source IP address (IPv4/IPv6). Useful on multi-homed hosts to originate connections from a specific address or enforce source routing. Examples: "192.168.1.10", "10.0.0.5", "2001:db8::1". The address must exist on the host and be routable or the connection may fail.
150
150
  # @param interface [String, nil] Bind to an interface on supported platforms; unsupported platforms raise ArgumentError.
@@ -178,7 +178,7 @@ unless defined?(Wreq)
178
178
  # @param deflate [Boolean, nil] Enable deflate compression
179
179
  # @param zstd [Boolean, nil] Enable Zstandard compression
180
180
  # @param timeout [Integer, nil] Total request timeout (seconds)
181
- # @param read_timeout [Integer, nil] Per-chunk read timeout (seconds)
181
+ # @param read_timeout [Integer, nil] Timeout for headers or each body chunk (seconds)
182
182
  # @param proxy [String, nil] Proxy server URI
183
183
  # @param local_address [String, nil] Bind the client's local source IP address (IPv4/IPv6). Useful on multi-homed hosts to originate connections from a specific address or enforce source routing. Examples: "192.168.1.10", "10.0.0.5", "2001:db8::1". The address must exist on the host and be routable or the connection may fail.
184
184
  # @param interface [String, nil] Bind to an interface on supported platforms; unsupported platforms raise ArgumentError.
@@ -212,7 +212,7 @@ unless defined?(Wreq)
212
212
  # @param deflate [Boolean, nil] Enable deflate compression
213
213
  # @param zstd [Boolean, nil] Enable Zstandard compression
214
214
  # @param timeout [Integer, nil] Total request timeout (seconds)
215
- # @param read_timeout [Integer, nil] Per-chunk read timeout (seconds)
215
+ # @param read_timeout [Integer, nil] Timeout for headers or each body chunk (seconds)
216
216
  # @param proxy [String, nil] Proxy server URI
217
217
  # @param local_address [String, nil] Bind the client's local source IP address (IPv4/IPv6). Useful on multi-homed hosts to originate connections from a specific address or enforce source routing. Examples: "192.168.1.10", "10.0.0.5", "2001:db8::1". The address must exist on the host and be routable or the connection may fail.
218
218
  # @param interface [String, nil] Bind to an interface on supported platforms; unsupported platforms raise ArgumentError.
@@ -246,7 +246,7 @@ unless defined?(Wreq)
246
246
  # @param deflate [Boolean, nil] Enable deflate compression
247
247
  # @param zstd [Boolean, nil] Enable Zstandard compression
248
248
  # @param timeout [Integer, nil] Total request timeout (seconds)
249
- # @param read_timeout [Integer, nil] Per-chunk read timeout (seconds)
249
+ # @param read_timeout [Integer, nil] Timeout for headers or each body chunk (seconds)
250
250
  # @param proxy [String, nil] Proxy server URI
251
251
  # @param local_address [String, nil] Bind the client's local source IP address (IPv4/IPv6). Useful on multi-homed hosts to originate connections from a specific address or enforce source routing. Examples: "192.168.1.10", "10.0.0.5", "2001:db8::1". The address must exist on the host and be routable or the connection may fail.
252
252
  # @param interface [String, nil] Bind to an interface on supported platforms; unsupported platforms raise ArgumentError.
@@ -280,7 +280,7 @@ unless defined?(Wreq)
280
280
  # @param deflate [Boolean, nil] Enable deflate compression
281
281
  # @param zstd [Boolean, nil] Enable Zstandard compression
282
282
  # @param timeout [Integer, nil] Total request timeout (seconds)
283
- # @param read_timeout [Integer, nil] Per-chunk read timeout (seconds)
283
+ # @param read_timeout [Integer, nil] Timeout for headers or each body chunk (seconds)
284
284
  # @param proxy [String, nil] Proxy server URI
285
285
  # @param local_address [String, nil] Bind the client's local source IP address (IPv4/IPv6). Useful on multi-homed hosts to originate connections from a specific address or enforce source routing. Examples: "192.168.1.10", "10.0.0.5", "2001:db8::1". The address must exist on the host and be routable or the connection may fail.
286
286
  # @param interface [String, nil] Bind to an interface on supported platforms; unsupported platforms raise ArgumentError.
@@ -314,7 +314,7 @@ unless defined?(Wreq)
314
314
  # @param deflate [Boolean, nil] Enable deflate compression
315
315
  # @param zstd [Boolean, nil] Enable Zstandard compression
316
316
  # @param timeout [Integer, nil] Total request timeout (seconds)
317
- # @param read_timeout [Integer, nil] Per-chunk read timeout (seconds)
317
+ # @param read_timeout [Integer, nil] Timeout for headers or each body chunk (seconds)
318
318
  # @param proxy [String, nil] Proxy server URI
319
319
  # @param local_address [String, nil] Bind the client's local source IP address (IPv4/IPv6). Useful on multi-homed hosts to originate connections from a specific address or enforce source routing. Examples: "192.168.1.10", "10.0.0.5", "2001:db8::1". The address must exist on the host and be routable or the connection may fail.
320
320
  # @param interface [String, nil] Bind to an interface on supported platforms; unsupported platforms raise ArgumentError.
@@ -348,7 +348,7 @@ unless defined?(Wreq)
348
348
  # @param deflate [Boolean, nil] Enable deflate compression
349
349
  # @param zstd [Boolean, nil] Enable Zstandard compression
350
350
  # @param timeout [Integer, nil] Total request timeout (seconds)
351
- # @param read_timeout [Integer, nil] Per-chunk read timeout (seconds)
351
+ # @param read_timeout [Integer, nil] Timeout for headers or each body chunk (seconds)
352
352
  # @param proxy [String, nil] Proxy server URI
353
353
  # @param local_address [String, nil] Bind the client's local source IP address (IPv4/IPv6). Useful on multi-homed hosts to originate connections from a specific address or enforce source routing. Examples: "192.168.1.10", "10.0.0.5", "2001:db8::1". The address must exist on the host and be routable or the connection may fail.
354
354
  # @param interface [String, nil] Bind to an interface on supported platforms; unsupported platforms raise ArgumentError.
@@ -84,8 +84,8 @@ unless defined?(Wreq)
84
84
  # from the overall timeout.
85
85
  #
86
86
  # @param read_timeout [Integer, nil] Maximum time in seconds to wait
87
- # between reading chunks of data from the server. Applies to each
88
- # read operation, not the entire response.
87
+ # for response headers or each body chunk. Time spent by the caller
88
+ # between body reads is excluded. Defaults to no read timeout.
89
89
  #
90
90
  # @param tcp_keepalive [Integer, nil] Time in seconds that a connection
91
91
  # must be idle before TCP keepalive probes are sent. Helps detect
@@ -196,7 +196,7 @@ unless defined?(Wreq)
196
196
  # client = Wreq::Client.new(
197
197
  # timeout: 30, # 30 seconds total
198
198
  # connect_timeout: 5, # 5 seconds to connect
199
- # read_timeout: 10 # 10 seconds between reads
199
+ # read_timeout: 10 # 10 seconds for headers or each body read
200
200
  # )
201
201
  #
202
202
  # @example Client with redirect handling
@@ -280,7 +280,7 @@ unless defined?(Wreq)
280
280
  # @param deflate [Boolean, nil] Enable deflate compression
281
281
  # @param zstd [Boolean, nil] Enable Zstandard compression
282
282
  # @param timeout [Integer, nil] Total request timeout (seconds)
283
- # @param read_timeout [Integer, nil] Per-chunk read timeout (seconds)
283
+ # @param read_timeout [Integer, nil] Timeout for headers or each body chunk (seconds)
284
284
  # @param proxy [String, nil] Proxy server URI
285
285
  # @param local_address [String, nil] Bind the request's local source IP address (IPv4/IPv6). Useful on multi-homed hosts to originate connections from a specific address or enforce source routing. Examples: "192.168.1.10", "10.0.0.5", "2001:db8::1". The address must exist on the host and be routable or the connection may fail.
286
286
  # @param interface [String, nil] Bind to an interface on supported platforms; unsupported platforms raise ArgumentError.
@@ -316,7 +316,7 @@ unless defined?(Wreq)
316
316
  # @param deflate [Boolean, nil] Enable deflate compression
317
317
  # @param zstd [Boolean, nil] Enable Zstandard compression
318
318
  # @param timeout [Integer, nil] Total request timeout (seconds)
319
- # @param read_timeout [Integer, nil] Per-chunk read timeout (seconds)
319
+ # @param read_timeout [Integer, nil] Timeout for headers or each body chunk (seconds)
320
320
  # @param proxy [String, nil] Proxy server URI
321
321
  # @param local_address [String, nil] Bind the request's local source IP address (IPv4/IPv6). Useful on multi-homed hosts to originate connections from a specific address or enforce source routing. Examples: "192.168.1.10", "10.0.0.5", "2001:db8::1". The address must exist on the host and be routable or the connection may fail.
322
322
  # @param interface [String, nil] Bind to an interface on supported platforms; unsupported platforms raise ArgumentError.
@@ -350,7 +350,7 @@ unless defined?(Wreq)
350
350
  # @param deflate [Boolean, nil] Enable deflate compression
351
351
  # @param zstd [Boolean, nil] Enable Zstandard compression
352
352
  # @param timeout [Integer, nil] Total request timeout (seconds)
353
- # @param read_timeout [Integer, nil] Per-chunk read timeout (seconds)
353
+ # @param read_timeout [Integer, nil] Timeout for headers or each body chunk (seconds)
354
354
  # @param proxy [String, nil] Proxy server URI
355
355
  # @param local_address [String, nil] Bind the request's local source IP address (IPv4/IPv6). Useful on multi-homed hosts to originate connections from a specific address or enforce source routing. Examples: "192.168.1.10", "10.0.0.5", "2001:db8::1". The address must exist on the host and be routable or the connection may fail.
356
356
  # @param interface [String, nil] Bind to an interface on supported platforms; unsupported platforms raise ArgumentError.
@@ -384,7 +384,7 @@ unless defined?(Wreq)
384
384
  # @param deflate [Boolean, nil] Enable deflate compression
385
385
  # @param zstd [Boolean, nil] Enable Zstandard compression
386
386
  # @param timeout [Integer, nil] Total request timeout (seconds)
387
- # @param read_timeout [Integer, nil] Per-chunk read timeout (seconds)
387
+ # @param read_timeout [Integer, nil] Timeout for headers or each body chunk (seconds)
388
388
  # @param proxy [String, nil] Proxy server URI
389
389
  # @param local_address [String, nil] Bind the request's local source IP address (IPv4/IPv6). Useful on multi-homed hosts to originate connections from a specific address or enforce source routing. Examples: "192.168.1.10", "10.0.0.5", "2001:db8::1". The address must exist on the host and be routable or the connection may fail.
390
390
  # @param interface [String, nil] Bind to an interface on supported platforms; unsupported platforms raise ArgumentError.
@@ -418,7 +418,7 @@ unless defined?(Wreq)
418
418
  # @param deflate [Boolean, nil] Enable deflate compression
419
419
  # @param zstd [Boolean, nil] Enable Zstandard compression
420
420
  # @param timeout [Integer, nil] Total request timeout (seconds)
421
- # @param read_timeout [Integer, nil] Per-chunk read timeout (seconds)
421
+ # @param read_timeout [Integer, nil] Timeout for headers or each body chunk (seconds)
422
422
  # @param proxy [String, nil] Proxy server URI
423
423
  # @param local_address [String, nil] Bind the request's local source IP address (IPv4/IPv6). Useful on multi-homed hosts to originate connections from a specific address or enforce source routing. Examples: "192.168.1.10", "10.0.0.5", "2001:db8::1". The address must exist on the host and be routable or the connection may fail.
424
424
  # @param interface [String, nil] Bind to an interface on supported platforms; unsupported platforms raise ArgumentError.
@@ -452,7 +452,7 @@ unless defined?(Wreq)
452
452
  # @param deflate [Boolean, nil] Enable deflate compression
453
453
  # @param zstd [Boolean, nil] Enable Zstandard compression
454
454
  # @param timeout [Integer, nil] Total request timeout (seconds)
455
- # @param read_timeout [Integer, nil] Per-chunk read timeout (seconds)
455
+ # @param read_timeout [Integer, nil] Timeout for headers or each body chunk (seconds)
456
456
  # @param proxy [String, nil] Proxy server URI
457
457
  # @param local_address [String, nil] Bind the request's local source IP address (IPv4/IPv6). Useful on multi-homed hosts to originate connections from a specific address or enforce source routing. Examples: "192.168.1.10", "10.0.0.5", "2001:db8::1". The address must exist on the host and be routable or the connection may fail.
458
458
  # @param interface [String, nil] Bind to an interface on supported platforms; unsupported platforms raise ArgumentError.
@@ -486,7 +486,7 @@ unless defined?(Wreq)
486
486
  # @param deflate [Boolean, nil] Enable deflate compression
487
487
  # @param zstd [Boolean, nil] Enable Zstandard compression
488
488
  # @param timeout [Integer, nil] Total request timeout (seconds)
489
- # @param read_timeout [Integer, nil] Per-chunk read timeout (seconds)
489
+ # @param read_timeout [Integer, nil] Timeout for headers or each body chunk (seconds)
490
490
  # @param proxy [String, nil] Proxy server URI
491
491
  # @param local_address [String, nil] Bind the request's local source IP address (IPv4/IPv6). Useful on multi-homed hosts to originate connections from a specific address or enforce source routing. Examples: "192.168.1.10", "10.0.0.5", "2001:db8::1". The address must exist on the host and be routable or the connection may fail.
492
492
  # @param interface [String, nil] Bind to an interface on supported platforms; unsupported platforms raise ArgumentError.
@@ -520,7 +520,7 @@ unless defined?(Wreq)
520
520
  # @param deflate [Boolean, nil] Enable deflate compression
521
521
  # @param zstd [Boolean, nil] Enable Zstandard compression
522
522
  # @param timeout [Integer, nil] Total request timeout (seconds)
523
- # @param read_timeout [Integer, nil] Per-chunk read timeout (seconds)
523
+ # @param read_timeout [Integer, nil] Timeout for headers or each body chunk (seconds)
524
524
  # @param proxy [String, nil] Proxy server URI
525
525
  # @param local_address [String, nil] Bind the request's local source IP address (IPv4/IPv6). Useful on multi-homed hosts to originate connections from a specific address or enforce source routing. Examples: "192.168.1.10", "10.0.0.5", "2001:db8::1". The address must exist on the host and be routable or the connection may fail.
526
526
  # @param interface [String, nil] Bind to an interface on supported platforms; unsupported platforms raise ArgumentError.
@@ -554,7 +554,7 @@ unless defined?(Wreq)
554
554
  # @param deflate [Boolean, nil] Enable deflate compression
555
555
  # @param zstd [Boolean, nil] Enable Zstandard compression
556
556
  # @param timeout [Integer, nil] Total request timeout (seconds)
557
- # @param read_timeout [Integer, nil] Per-chunk read timeout (seconds)
557
+ # @param read_timeout [Integer, nil] Timeout for headers or each body chunk (seconds)
558
558
  # @param proxy [String, nil] Proxy server URI
559
559
  # @param local_address [String, nil] Bind the request's local source IP address (IPv4/IPv6). Useful on multi-homed hosts to originate connections from a specific address or enforce source routing. Examples: "192.168.1.10", "10.0.0.5", "2001:db8::1". The address must exist on the host and be routable or the connection may fail.
560
560
  # @param interface [String, nil] Bind to an interface on supported platforms; unsupported platforms raise ArgumentError.
@@ -66,6 +66,8 @@ module Wreq
66
66
  Chrome152 = nil
67
67
  Chrome153 = nil
68
68
  Chrome154 = nil
69
+ Chrome155 = nil
70
+ Chrome156 = nil
69
71
 
70
72
  Edge101 = nil
71
73
  Edge122 = nil
@@ -266,7 +268,7 @@ module Wreq
266
268
  #
267
269
  # Construction generates the native configuration once. For Chrome 152/153,
268
270
  # the TLS trust_anchors extension's ID order is randomized at construction;
269
- # Chrome 154 sorts those IDs by their raw bytes instead. Reusing this object
271
+ # Chrome 154–156 sort those IDs by their raw bytes instead. Reusing this object
270
272
  # across clients or requests retains that order. Creating a new object generates
271
273
  # a new configuration, including a fresh shuffle for Chrome 152/153.
272
274
  # This does not freeze other per-handshake randomness or force a new handshake
@@ -298,8 +300,8 @@ module Wreq
298
300
  # This stub is for documentation only.
299
301
  unless singleton_methods(false).include?(:new)
300
302
  # Generates a reusable native configuration. Chrome 152/153 Trust Anchor ID
301
- # order is chosen here and retained when this object is reused; Chrome 154
302
- # uses raw-byte sorted order. See {Emulation} for connection semantics.
303
+ # order is chosen here and retained when this object is reused; Chrome 154–156
304
+ # use raw-byte sorted order. See {Emulation} for connection semantics.
303
305
  #
304
306
  # @param profile [Wreq::Profile, nil] Fingerprint profile to emulate
305
307
  # @param platform [Wreq::Platform, nil] Operating system platform to emulate
data/src/emulate.rs CHANGED
@@ -92,6 +92,8 @@ define_ruby_enum!(
92
92
  Chrome152,
93
93
  Chrome153,
94
94
  Chrome154,
95
+ Chrome155,
96
+ Chrome156,
95
97
 
96
98
  Edge101,
97
99
  Edge122,
@@ -7,7 +7,7 @@ require "timeout"
7
7
 
8
8
  class EmulationTest < Minitest::Test
9
9
  def test_reused_emulation_retains_trust_anchors_across_clients_and_requests
10
- [Wreq::Profile::Chrome152, Wreq::Profile::Chrome153, Wreq::Profile::Chrome154].each do |profile|
10
+ [Wreq::Profile::Chrome152, Wreq::Profile::Chrome153, Wreq::Profile::Chrome154, Wreq::Profile::Chrome155, Wreq::Profile::Chrome156].each do |profile|
11
11
  emulation = Wreq::Emulation.new(profile: profile)
12
12
  client = Wreq::Client.new(emulation: emulation, no_proxy: true)
13
13
  expected = capture_trust_anchors { |url| client.get(url, timeout: 5) }
@@ -43,6 +43,8 @@ class EmulationTest < Minitest::Test
43
43
  Wreq::Profile::Chrome152 => "Chrome152",
44
44
  Wreq::Profile::Chrome153 => "Chrome153",
45
45
  Wreq::Profile::Chrome154 => "Chrome154",
46
+ Wreq::Profile::Chrome155 => "Chrome155",
47
+ Wreq::Profile::Chrome156 => "Chrome156",
46
48
  Wreq::Profile::Firefox152 => "Firefox152"
47
49
  }.each do |profile, name|
48
50
  assert_equal name, profile.to_s
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wreq
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - SearchApi