wreq 1.2.12 → 1.2.14

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: dfff227b1aca526697d055128ca828a911403c337796d840e45667554ece669a
4
- data.tar.gz: ce36c588548df0a31e769fa54b226561d2e5b84cf0dd681c0102575503803e86
3
+ metadata.gz: 9d959831cb8e18b4615af45265459779489d427c028879a8730668fd45882ccf
4
+ data.tar.gz: 1979a1b7207b7655988bad7d7f0b489671d8d2f954950cdc98996616cd20bc74
5
5
  SHA512:
6
- metadata.gz: 77c99a185649091bc2c537efbdf4490404ef113c250a733ab47c3f49ac574659b455e78a3a77efe2f95ca9739b88b0f8ed6452b51d8583b01de7aaf4d88a1d0c
7
- data.tar.gz: df326eb44d85324d981fb9a624f52a87d30871836f093dbde2ecd9c8b7b9b76cb786e8f2c2cd15aed1d2237fe8b9fc33a34803bf74972fb15a1bb9e8296071e5
6
+ metadata.gz: 685dbec532a27d62840e5dca70888f17ac1da268bf564ccdb1efbc399068df06bcf4e79c3e2db0c4d7d74f534d3a9b435595681708d4bccbbf44d8535889d70f
7
+ data.tar.gz: ec607cbbc36f30e79792c33fda253ebf2ee0257a19941a18c2f1af1074232932b96f9bc4699f9b4f3a7f61f7496aeb0d618d275873cde01cc0ac8b1db9049529
data/Cargo.lock CHANGED
@@ -113,7 +113,7 @@ dependencies = [
113
113
  [[package]]
114
114
  name = "btls"
115
115
  version = "0.5.6"
116
- source = "git+https://github.com/0x676e67/btls?branch=demo%2Fmerge-upstream-boring-20260616#2c1026a045e31454e841f96c6dfb594d5a4e4752"
116
+ source = "git+https://github.com/0x676e67/btls?rev=de7ab84fdb58641a2bdfdf9d8ebd7db1dcf4b29b#de7ab84fdb58641a2bdfdf9d8ebd7db1dcf4b29b"
117
117
  dependencies = [
118
118
  "bitflags",
119
119
  "btls-sys",
@@ -125,7 +125,7 @@ dependencies = [
125
125
  [[package]]
126
126
  name = "btls-sys"
127
127
  version = "0.5.6"
128
- source = "git+https://github.com/0x676e67/btls?branch=demo%2Fmerge-upstream-boring-20260616#2c1026a045e31454e841f96c6dfb594d5a4e4752"
128
+ source = "git+https://github.com/0x676e67/btls?rev=de7ab84fdb58641a2bdfdf9d8ebd7db1dcf4b29b#de7ab84fdb58641a2bdfdf9d8ebd7db1dcf4b29b"
129
129
  dependencies = [
130
130
  "bindgen",
131
131
  "cmake",
@@ -166,6 +166,15 @@ version = "1.0.4"
166
166
  source = "registry+https://github.com/rust-lang/crates.io-index"
167
167
  checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
168
168
 
169
+ [[package]]
170
+ name = "chromium-roots"
171
+ version = "0.1.1"
172
+ source = "registry+https://github.com/rust-lang/crates.io-index"
173
+ checksum = "229b200495e6cf4d4b599a1884c30f5af57898604e6c0bd94a217295c0d1df69"
174
+ dependencies = [
175
+ "rustls-pki-types",
176
+ ]
177
+
169
178
  [[package]]
170
179
  name = "clang-sys"
171
180
  version = "1.9.1"
@@ -1270,9 +1279,9 @@ dependencies = [
1270
1279
 
1271
1280
  [[package]]
1272
1281
  name = "tower-http"
1273
- version = "0.6.11"
1282
+ version = "0.7.1"
1274
1283
  source = "registry+https://github.com/rust-lang/crates.io-index"
1275
- checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840"
1284
+ checksum = "08a05a66a4fdd61cbbe0a1d755ffe0ca6aba159dd4820936a0ff8a8278245b9c"
1276
1285
  dependencies = [
1277
1286
  "async-compression",
1278
1287
  "bitflags",
@@ -1281,6 +1290,7 @@ dependencies = [
1281
1290
  "http",
1282
1291
  "http-body",
1283
1292
  "http-body-util",
1293
+ "percent-encoding",
1284
1294
  "pin-project-lite",
1285
1295
  "tokio",
1286
1296
  "tokio-util",
@@ -1371,15 +1381,6 @@ version = "0.11.1+wasi-snapshot-preview1"
1371
1381
  source = "registry+https://github.com/rust-lang/crates.io-index"
1372
1382
  checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
1373
1383
 
1374
- [[package]]
1375
- name = "webpki-root-certs"
1376
- version = "1.0.9"
1377
- source = "registry+https://github.com/rust-lang/crates.io-index"
1378
- checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b"
1379
- dependencies = [
1380
- "rustls-pki-types",
1381
- ]
1382
-
1383
1384
  [[package]]
1384
1385
  name = "winapi"
1385
1386
  version = "0.3.9"
@@ -1419,12 +1420,13 @@ dependencies = [
1419
1420
 
1420
1421
  [[package]]
1421
1422
  name = "wreq"
1422
- version = "6.0.0-rc.29"
1423
- source = "git+https://github.com/0x676e67/wreq?rev=12ccf64bb00e79db6eabd4bc3ccf82871d3eb5a5#12ccf64bb00e79db6eabd4bc3ccf82871d3eb5a5"
1423
+ version = "0.16.1"
1424
+ source = "git+https://github.com/0x676e67/wreq?rev=abd421d16dd48b3c2d7fb812f185eec3c6ec3132#abd421d16dd48b3c2d7fb812f185eec3c6ec3132"
1424
1425
  dependencies = [
1425
1426
  "btls",
1426
1427
  "btls-sys",
1427
1428
  "bytes",
1429
+ "chromium-roots",
1428
1430
  "cookie",
1429
1431
  "encoding_rs",
1430
1432
  "futures-util",
@@ -1451,7 +1453,6 @@ dependencies = [
1451
1453
  "tower",
1452
1454
  "tower-http",
1453
1455
  "url",
1454
- "webpki-root-certs",
1455
1456
  "wreq-proto",
1456
1457
  "wreq-rt",
1457
1458
  ]
@@ -1489,7 +1490,7 @@ dependencies = [
1489
1490
 
1490
1491
  [[package]]
1491
1492
  name = "wreq-ruby"
1492
- version = "1.2.12"
1493
+ version = "1.2.14"
1493
1494
  dependencies = [
1494
1495
  "arc-swap",
1495
1496
  "bytes",
@@ -1516,6 +1517,7 @@ name = "wreq-util"
1516
1517
  version = "3.0.0-rc.14"
1517
1518
  dependencies = [
1518
1519
  "brotli",
1520
+ "chromium-roots",
1519
1521
  "flate2",
1520
1522
  "typed-builder",
1521
1523
  "wreq",
data/Cargo.toml CHANGED
@@ -5,8 +5,8 @@ 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.2.12"
9
- rust-version = "1.95"
8
+ version = "1.2.14"
9
+ rust-version = "1.98"
10
10
 
11
11
  [lib]
12
12
  crate-type = ["cdylib"]
@@ -17,7 +17,7 @@ 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 = "6.0.0-rc", features = [
20
+ wreq = { version = "0.16.1", features = [
21
21
  "query",
22
22
  "form",
23
23
  "json",
@@ -65,7 +65,7 @@ strip = true
65
65
 
66
66
  [patch.crates-io]
67
67
  http2 = { git = "https://github.com/0x676e67/http2", rev = "b413a92b2e1fe7e2ea1b7be78e75b872386fdfa0" }
68
- btls = { git = "https://github.com/0x676e67/btls", branch = "demo/merge-upstream-boring-20260616" }
69
- btls-sys = { git = "https://github.com/0x676e67/btls", branch = "demo/merge-upstream-boring-20260616" }
70
- wreq = { git = "https://github.com/0x676e67/wreq", rev = "12ccf64bb00e79db6eabd4bc3ccf82871d3eb5a5" }
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" }
71
71
  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` |
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` |
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` |
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` |
@@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
10
10
  ### Added
11
11
 
12
12
  - *(emulate)* Add Chrome 151 profile.
13
+ - *(emulate)* Add Chrome 152 profile.
14
+ - *(emulate)* Add Chrome 153 profile.
13
15
 
14
16
  ## [3.0.0-rc.14](https://github.com/0x676e67/wreq-util/compare/v3.0.0-rc.13...v3.0.0-rc.14) - 2026-07-04
15
17
 
@@ -9,7 +9,7 @@ version = "3.0.0-rc.14"
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
11
11
  edition = "2024"
12
- rust-version = "1.85"
12
+ rust-version = "1.98"
13
13
 
14
14
  [package.metadata.docs.rs]
15
15
  all-features = true
@@ -22,14 +22,21 @@ default = ["emulation"]
22
22
  tokio-rt = ["wreq/tokio-rt"]
23
23
  compio-rt = ["wreq/compio-rt"]
24
24
 
25
- emulation = ["dep:typed-builder", "dep:brotli", "dep:flate2", "dep:zstd"]
25
+ emulation = [
26
+ "dep:typed-builder",
27
+ "dep:brotli",
28
+ "dep:flate2",
29
+ "dep:zstd",
30
+ "dep:chromium-roots",
31
+ "wreq/chromium-roots",
32
+ ]
26
33
  emulation-serde = ["dep:serde"]
27
34
  emulation-compression = []
28
35
 
29
36
  tower-delay = ["dep:tower", "dep:pin-project-lite", "tokio/time"]
30
37
 
31
38
  [dependencies]
32
- wreq = { version = "6.0.0-rc", default-features = false }
39
+ wreq = { version = "0.16.1", default-features = false }
33
40
 
34
41
  # Optional deps...
35
42
 
@@ -38,6 +45,7 @@ tokio = { version = "1.52.1", default-features = false, optional = true }
38
45
  tower = { version = "0.5.2", default-features = false, optional = true }
39
46
  typed-builder = { version = "0.23.2", optional = true }
40
47
  pin-project-lite = { version = "0.2.17", optional = true }
48
+ chromium-roots = { version = "0.1.1", optional = true }
41
49
 
42
50
  ## Compression algorithms
43
51
  brotli = { version = "8.0.2", optional = true }
@@ -45,7 +53,7 @@ flate2 = { version = "1.1.9", optional = true }
45
53
  zstd = { version = "0.13.3", optional = true }
46
54
 
47
55
  [dev-dependencies]
48
- wreq = "6.0.0-rc"
56
+ wreq = "0.16.1"
49
57
  tokio = { version = "1.48.0", features = ["full"] }
50
58
  hyper = { version = "1.10.1", default-features = false, features = [
51
59
  "http1",
@@ -131,6 +131,13 @@ macro_rules! header_chrome_accept_encoding {
131
131
  );
132
132
  $headers.insert(ACCEPT_LANGUAGE, HeaderValue::from_static("en-US,en;q=0.9"));
133
133
  };
134
+ (zstd_only, $headers:expr) => {
135
+ #[cfg(feature = "emulation-compression")]
136
+ $headers.insert(
137
+ ACCEPT_ENCODING,
138
+ HeaderValue::from_static("gzip, deflate, br, zstd"),
139
+ );
140
+ };
134
141
  }
135
142
 
136
143
  macro_rules! header_firefox_sec_fetch {
@@ -72,3 +72,31 @@ pub fn header_initializer_with_zstd_priority(
72
72
  );
73
73
  headers
74
74
  }
75
+
76
+ pub fn header_initializer_chrome152(
77
+ sec_ch_ua: &'static str,
78
+ ua: &'static str,
79
+ emulation_os: Platform,
80
+ ) -> HeaderMap {
81
+ let mut headers = HeaderMap::new();
82
+ header_chrome_sec_ch_ua!(
83
+ headers,
84
+ sec_ch_ua,
85
+ emulation_os.platform(),
86
+ emulation_os.is_mobile()
87
+ );
88
+ headers.insert(ACCEPT_LANGUAGE, HeaderValue::from_static("en-US,en;q=0.9"));
89
+ headers.insert(
90
+ HeaderName::from_static("upgrade-insecure-requests"),
91
+ HeaderValue::from_static("1"),
92
+ );
93
+ header_chrome_ua!(headers, ua);
94
+ header_chrome_accept!(headers);
95
+ header_chrome_sec_fetch!(headers);
96
+ header_chrome_accept_encoding!(zstd_only, headers);
97
+ headers.insert(
98
+ HeaderName::from_static("priority"),
99
+ HeaderValue::from_static("u=0, i"),
100
+ );
101
+ headers
102
+ }
@@ -49,6 +49,17 @@ macro_rules! tls_options {
49
49
  .sigalgs_list($sigalgs)
50
50
  .alps_use_new_codepoint(true))
51
51
  };
52
+ (9, $curves:expr) => {
53
+ tls_options!(@build ChromeTlsConfig::builder()
54
+ .permute_extensions(true)
55
+ .enable_ech_grease(true)
56
+ .pre_shared_key(true)
57
+ .curves($curves)
58
+ .sigalgs_list(NEW_SIGALGS_LIST)
59
+ .trust_anchors(CHROME_TRUST_ANCHORS)
60
+ .grease_sigalgs_enabled(true)
61
+ .alps_use_new_codepoint(true))
62
+ };
52
63
  }
53
64
 
54
65
  pub const CURVES_1: &str = join!(":", "X25519", "P-256", "P-384");
@@ -101,6 +112,9 @@ pub const NEW_SIGALGS_LIST: &str = join!(
101
112
  "rsa_pkcs1_sha512"
102
113
  );
103
114
 
115
+ // Encoded IDs and wreq's Chromium root store come from the same root set.
116
+ pub(super) const CHROME_TRUST_ANCHORS: &[u8] = &chromium_roots::encoded_trust_anchor_ids();
117
+
104
118
  pub const CERTIFICATE_COMPRESSORS: &[&'static dyn CertificateCompressor] = &[&BrotliCompressor];
105
119
 
106
120
  #[derive(TypedBuilder)]
@@ -128,11 +142,17 @@ pub struct ChromeTlsConfig {
128
142
 
129
143
  #[builder(default = false, setter(into))]
130
144
  pre_shared_key: bool,
145
+
146
+ #[builder(default, setter(strip_option))]
147
+ trust_anchors: Option<&'static [u8]>,
148
+
149
+ #[builder(default, setter(strip_option))]
150
+ grease_sigalgs_enabled: Option<bool>,
131
151
  }
132
152
 
133
153
  impl From<ChromeTlsConfig> for TlsOptions {
134
154
  fn from(val: ChromeTlsConfig) -> Self {
135
- TlsOptions::builder()
155
+ let builder = TlsOptions::builder()
136
156
  .grease_enabled(true)
137
157
  .enable_ocsp_stapling(true)
138
158
  .enable_signed_cert_timestamps(true)
@@ -147,7 +167,17 @@ impl From<ChromeTlsConfig> for TlsOptions {
147
167
  .alps_protocols([val.alps_protos])
148
168
  .alps_use_new_codepoint(val.alps_use_new_codepoint)
149
169
  .aes_hw_override(true)
150
- .certificate_compressors(CERTIFICATE_COMPRESSORS)
151
- .build()
170
+ .certificate_compressors(CERTIFICATE_COMPRESSORS);
171
+ let builder = if let Some(trust_anchors) = val.trust_anchors {
172
+ builder.trust_anchors(trust_anchors)
173
+ } else {
174
+ builder
175
+ };
176
+ let builder = if let Some(enabled) = val.grease_sigalgs_enabled {
177
+ builder.grease_sigalgs_enabled(enabled)
178
+ } else {
179
+ builder
180
+ };
181
+ builder.build()
152
182
  }
153
183
  }
@@ -1862,6 +1862,73 @@ mod_generator!(
1862
1862
  ]
1863
1863
  );
1864
1864
 
1865
+ mod_generator!(
1866
+ v152,
1867
+ tls_options!(9, CURVES_3),
1868
+ http2_options!(3),
1869
+ header_initializer_chrome152,
1870
+ [
1871
+ (
1872
+ MacOS,
1873
+ r#""Chromium";v="152", "Not?A_Brand";v="24", "Google Chrome";v="152""#,
1874
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36"
1875
+ ),
1876
+ (
1877
+ Linux,
1878
+ r#""Chromium";v="152", "Not?A_Brand";v="24", "Google Chrome";v="152""#,
1879
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36"
1880
+ ),
1881
+ (
1882
+ Android,
1883
+ r#""Chromium";v="152", "Not?A_Brand";v="24", "Google Chrome";v="152""#,
1884
+ "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Mobile Safari/537.36"
1885
+ ),
1886
+ (
1887
+ Windows,
1888
+ r#""Chromium";v="152", "Not?A_Brand";v="24", "Google Chrome";v="152""#,
1889
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36"
1890
+ ),
1891
+ (
1892
+ IOS,
1893
+ r#""Chromium";v="152", "Not?A_Brand";v="24", "Google Chrome";v="152""#,
1894
+ "Mozilla/5.0 (iPhone; CPU iPhone OS 18_7_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/152.0.0.0 Mobile/15E148 Safari/604.1"
1895
+ )
1896
+ ]
1897
+ );
1898
+
1899
+ mod_generator!(
1900
+ v153,
1901
+ v152::build_emulation,
1902
+ header_initializer_with_zstd_priority,
1903
+ [
1904
+ (
1905
+ MacOS,
1906
+ r#""Google Chrome";v="153", "Not_A Brand";v="8", "Chromium";v="153""#,
1907
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36"
1908
+ ),
1909
+ (
1910
+ Linux,
1911
+ r#""Google Chrome";v="153", "Not_A Brand";v="8", "Chromium";v="153""#,
1912
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36"
1913
+ ),
1914
+ (
1915
+ Android,
1916
+ r#""Google Chrome";v="153", "Not_A Brand";v="8", "Chromium";v="153""#,
1917
+ "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Mobile Safari/537.36"
1918
+ ),
1919
+ (
1920
+ Windows,
1921
+ r#""Google Chrome";v="153", "Not_A Brand";v="8", "Chromium";v="153""#,
1922
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36"
1923
+ ),
1924
+ (
1925
+ IOS,
1926
+ r#""Google Chrome";v="153", "Not_A Brand";v="8", "Chromium";v="153""#,
1927
+ "Mozilla/5.0 (iPhone; CPU iPhone OS 18_7_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/153.0.8010.24 Mobile/15E148 Safari/604.1"
1928
+ )
1929
+ ]
1930
+ );
1931
+
1865
1932
  mod_generator!(
1866
1933
  edge143,
1867
1934
  v132::build_emulation,
@@ -62,6 +62,8 @@ define_enum!(
62
62
  Chrome149 => ("chrome_149", v149::emulation),
63
63
  Chrome150 => ("chrome_150", v150::emulation),
64
64
  Chrome151 => ("chrome_151", v151::emulation),
65
+ Chrome152 => ("chrome_152", v152::emulation),
66
+ Chrome153 => ("chrome_153", v153::emulation),
65
67
 
66
68
  // Edge versions
67
69
  Edge101 => ("edge_101", edge101::emulation),
@@ -275,3 +275,23 @@ test_emulation!(
275
275
  ["t13d1516h2_8daaf6152771_806a8c22fdea"],
276
276
  "52d84b11737d980aef856699f885ca86"
277
277
  );
278
+
279
+ test_emulation!(
280
+ test_chrome152,
281
+ Emulation::Chrome152,
282
+ [
283
+ "t13d1517h2_8daaf6152771_cb7bf5808d99",
284
+ "t13d1518h2_8daaf6152771_e2d80978ab2e"
285
+ ],
286
+ "52d84b11737d980aef856699f885ca86"
287
+ );
288
+
289
+ test_emulation!(
290
+ test_chrome153,
291
+ Emulation::Chrome153,
292
+ [
293
+ "t13d1517h2_8daaf6152771_cb7bf5808d99",
294
+ "t13d1518h2_8daaf6152771_e2d80978ab2e"
295
+ ],
296
+ "52d84b11737d980aef856699f885ca86"
297
+ );
data/docs/fork-safety.md CHANGED
@@ -1,34 +1,51 @@
1
1
  # Fork safety
2
2
 
3
- ## Why inherited clients are rejected
4
-
5
- wreq-ruby uses a process-wide Tokio runtime and connection pool. `fork` copies
6
- the parent's memory, but only the thread that called `fork` continues in the
7
- child. Tokio's worker threads are gone, and its inherited tasks, locks, and
8
- connections are not safe to reuse.
9
-
10
- If the parent has already loaded wreq-ruby, native HTTP operations in the child
11
- raise `Wreq::ForkError`. This applies to new and existing clients, module
12
- request methods, streaming request bodies, and response methods backed by native
13
- state. Retrying the operation in the same child raises the same error. Read-only
14
- response metadata such as status, headers, and captured TLS information remains
15
- available.
16
-
17
- The parent can continue using its clients. When inherited Ruby objects are
18
- collected in the child, their native runtime state is left for the operating
19
- system to reclaim when the process exits.
20
-
21
- ## HTTP work in forked children is unsupported
22
-
23
- A process created with `fork` must not start or continue HTTP work through
24
- wreq-ruby, even when it first loads the extension after the fork. If the parent
25
- loaded wreq-ruby, native HTTP operations in the child raise `Wreq::ForkError`.
26
-
27
- When the extension was not present in the parent, no wreq-ruby state or fork
28
- marker reaches the child. The extension cannot reliably distinguish that child
29
- from a newly started process, so this unsupported path cannot guarantee a Ruby
30
- error and may fail inside platform libraries.
31
-
32
- Prefork servers should use an `exec`- or spawn-based worker model when workers
33
- need wreq-ruby. Requiring the extension again does not reset inherited runtime
34
- state, and there is no `after_fork!` hook.
3
+ ## Prefork checklist
4
+
5
+ - `require "wreq"` may run in the parent before workers fork.
6
+ - Create each `Wreq::Client`, `Wreq::Jar`, and `Wreq::BodySender` in the worker
7
+ that will use it.
8
+ - Keep each `Wreq::Response` in the process that received it.
9
+ - Do not start requests or push streaming body data in the parent before workers
10
+ fork.
11
+ - If the parent must use wreq-ruby first, start workers with `spawn` or `exec`
12
+ instead of `fork`.
13
+
14
+ wreq-ruby checks process ownership whenever it exposes guarded native state. It
15
+ does not copy, reset, or rebuild inherited objects.
16
+
17
+ ## Loading before fork
18
+
19
+ wreq-ruby creates its process-wide Tokio runtime on the first operation that
20
+ needs it. Requiring the gem does not initialize the runtime, so a prefork server
21
+ may load wreq-ruby during boot. Each worker can then create its own runtime on
22
+ its first request without an `after_fork!` hook.
23
+
24
+ Create clients and other native-backed objects inside the worker. Each client,
25
+ response, body sender, and cookie jar belongs to the process that created it.
26
+ Using an inherited object raises `Wreq::ForkError`, even when the parent never
27
+ started the runtime. wreq-ruby does not rebuild these objects.
28
+
29
+ ## Forking after runtime initialization
30
+
31
+ Once the parent starts an HTTP operation or otherwise uses the Tokio runtime, a
32
+ forked child must not reuse it. Tokio's worker threads do not survive `fork`, and
33
+ the inherited connection pool may refer to those missing threads.
34
+
35
+ Operations that need the inherited runtime raise `Wreq::ForkError`. This
36
+ includes requests through new or existing clients, module request methods, and
37
+ streaming request writes. Constructing a new client, body sender, or cookie jar
38
+ does not use the runtime, but runtime-backed operations remain unavailable in
39
+ that child. Retrying them raises the same error.
40
+
41
+ An inherited `Wreq::Response` cannot be used at all. This includes status,
42
+ headers, socket addresses, TLS information, and body methods. Values copied out
43
+ before the fork, such as a `Wreq::StatusCode` or `Wreq::TlsInfo`, are separate
44
+ objects and do not retain access to the response.
45
+
46
+ The parent remains usable. Native objects collected in the child do not destroy
47
+ state owned by the parent process.
48
+
49
+ Use a spawn- or exec-based worker when the parent must perform HTTP work before
50
+ workers start. Requiring the extension again cannot replace an inherited
51
+ runtime.
@@ -84,9 +84,10 @@ to the Ruby-owned thread with the GVL may [`src/rt.rs`](../src/rt.rs) map a
84
84
  wreq-owned cancellation to the `Wreq::InterruptError` defined in
85
85
  [`src/error.rs`](../src/error.rs).
86
86
 
87
- Keep this conversion centralized in `rt::try_block_on`. Request, response, and
88
- body operations may call `try_block_on`, but they must not construct their own
89
- Ruby cancellation exception.
87
+ Keep cancellation conversion centralized in `rt::block_on`. Request, response,
88
+ and body operations may call `block_on`, but they must not construct their own
89
+ Ruby cancellation exception. `block_on` returns a future's native error
90
+ unchanged so the caller can convert it after the GVL has been reacquired.
90
91
 
91
92
  These forms are forbidden for wreq-owned cancellation:
92
93