wreq-rb 0.4.0 → 0.5.1
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 +4 -4
- data/Cargo.lock +1922 -397
- data/LICENSE +203 -0
- data/README.md +47 -16
- data/exe/wreq +211 -0
- data/ext/wreq_rb/Cargo.toml +4 -6
- data/ext/wreq_rb/src/client.rs +145 -41
- data/lib/wreq-rb/version.rb +1 -1
- data/patches/0001-add-transfer-size-tracking.patch +76 -67
- data/vendor/wreq/Cargo.toml +119 -71
- data/vendor/wreq/README.md +25 -20
- data/vendor/wreq/bench/http1.rs +25 -0
- data/vendor/wreq/bench/http1_over_tls.rs +25 -0
- data/vendor/wreq/bench/http2.rs +25 -0
- data/vendor/wreq/bench/http2_over_tls.rs +25 -0
- data/vendor/wreq/bench/support/bench.rs +91 -0
- data/vendor/wreq/bench/support/client.rs +217 -0
- data/vendor/wreq/bench/support/server.rs +188 -0
- data/vendor/wreq/bench/support.rs +56 -0
- data/vendor/wreq/examples/cert_store.rs +4 -4
- data/vendor/wreq/examples/{emulation.rs → emulate.rs} +2 -2
- data/vendor/wreq/examples/http2_websocket.rs +2 -2
- data/vendor/wreq/examples/keylog.rs +3 -3
- data/vendor/wreq/examples/{request_with_emulation.rs → request_with_emulate.rs} +2 -2
- data/vendor/wreq/examples/rt.rs +23 -0
- data/vendor/wreq/src/client/body.rs +23 -61
- data/vendor/wreq/src/client/emulate.rs +119 -0
- data/vendor/wreq/src/client/{http/future.rs → future.rs} +11 -32
- data/vendor/wreq/src/client/{http → layer}/client/pool.rs +66 -61
- data/vendor/wreq/src/client/{http → layer}/client.rs +416 -270
- data/vendor/wreq/src/client/layer/config.rs +27 -6
- data/vendor/wreq/src/client/layer/decoder.rs +9 -4
- data/vendor/wreq/src/client/layer/redirect/future.rs +6 -3
- data/vendor/wreq/src/client/layer/redirect.rs +4 -5
- data/vendor/wreq/src/client/layer/retry.rs +8 -5
- data/vendor/wreq/src/client/layer/timeout/body.rs +15 -6
- data/vendor/wreq/src/client/layer/timeout/future.rs +23 -18
- data/vendor/wreq/src/client/layer/timeout.rs +24 -74
- data/vendor/wreq/src/client/layer.rs +1 -2
- data/vendor/wreq/src/client/multipart.rs +137 -154
- data/vendor/wreq/src/client/request.rs +202 -118
- data/vendor/wreq/src/client/response.rs +46 -45
- data/vendor/wreq/src/client/upgrade.rs +15 -0
- data/vendor/wreq/src/client/ws.rs +73 -25
- data/vendor/wreq/src/client.rs +1655 -17
- data/vendor/wreq/src/config.rs +11 -11
- data/vendor/wreq/src/{client/conn → conn}/connector.rs +139 -137
- data/vendor/wreq/src/conn/descriptor.rs +143 -0
- data/vendor/wreq/src/conn/http.rs +484 -0
- data/vendor/wreq/src/conn/net/io.rs +75 -0
- data/vendor/wreq/src/conn/net/tcp/compio.rs +71 -0
- data/vendor/wreq/src/conn/net/tcp/tokio.rs +57 -0
- data/vendor/wreq/src/conn/net/tcp.rs +561 -0
- data/vendor/wreq/src/conn/net/uds/compio.rs +60 -0
- data/vendor/wreq/src/{client/conn/uds.rs → conn/net/uds/tokio.rs} +18 -12
- data/vendor/wreq/src/conn/net/uds.rs +11 -0
- data/vendor/wreq/src/conn/net.rs +130 -0
- data/vendor/wreq/src/{client/conn → conn}/proxy/socks.rs +2 -9
- data/vendor/wreq/src/{client/conn → conn}/proxy/tunnel.rs +21 -56
- data/vendor/wreq/src/conn/tls_info.rs +47 -0
- data/vendor/wreq/src/{client/conn.rs → conn.rs} +202 -54
- data/vendor/wreq/src/cookie.rs +302 -142
- data/vendor/wreq/src/dns/gai/compio.rs +77 -0
- data/vendor/wreq/src/dns/gai/tokio.rs +90 -0
- data/vendor/wreq/src/dns/gai.rs +14 -164
- data/vendor/wreq/src/dns/hickory.rs +16 -23
- data/vendor/wreq/src/dns/resolve.rs +7 -41
- data/vendor/wreq/src/dns.rs +90 -7
- data/vendor/wreq/src/error.rs +57 -31
- data/vendor/wreq/src/ext.rs +25 -0
- data/vendor/wreq/src/group.rs +211 -0
- data/vendor/wreq/src/header.rs +100 -112
- data/vendor/wreq/src/lib.rs +124 -73
- data/vendor/wreq/src/proxy.rs +6 -20
- data/vendor/wreq/src/redirect.rs +1 -1
- data/vendor/wreq/src/rt.rs +208 -0
- data/vendor/wreq/src/sync.rs +97 -98
- data/vendor/wreq/src/tls/compress.rs +124 -0
- data/vendor/wreq/src/tls/conn/ext.rs +54 -45
- data/vendor/wreq/src/tls/conn/service.rs +14 -18
- data/vendor/wreq/src/tls/conn.rs +169 -241
- data/vendor/wreq/src/tls/keylog.rs +68 -5
- data/vendor/wreq/src/tls/session.rs +205 -0
- data/vendor/wreq/src/tls/{x509 → trust}/identity.rs +4 -21
- data/vendor/wreq/src/tls/{x509/parser.rs → trust/parse.rs} +1 -1
- data/vendor/wreq/src/tls/{x509 → trust}/store.rs +42 -81
- data/vendor/wreq/src/tls/{x509.rs → trust.rs} +8 -2
- data/vendor/wreq/src/tls.rs +489 -25
- data/vendor/wreq/src/trace.rs +0 -12
- data/vendor/wreq/src/util.rs +1 -1
- data/vendor/wreq/tests/badssl.rs +10 -10
- data/vendor/wreq/tests/client.rs +3 -9
- data/vendor/wreq/tests/cookie.rs +6 -8
- data/vendor/wreq/tests/{emulation.rs → emulate.rs} +130 -22
- data/vendor/wreq/tests/multipart.rs +43 -1
- data/vendor/wreq/tests/proxy.rs +1 -1
- data/vendor/wreq/tests/support/layer.rs +1 -0
- metadata +53 -72
- data/vendor/wreq/src/client/conn/conn.rs +0 -231
- data/vendor/wreq/src/client/conn/http.rs +0 -1023
- data/vendor/wreq/src/client/conn/tls_info.rs +0 -98
- data/vendor/wreq/src/client/core/body/incoming.rs +0 -485
- data/vendor/wreq/src/client/core/body/length.rs +0 -118
- data/vendor/wreq/src/client/core/body.rs +0 -34
- data/vendor/wreq/src/client/core/common/buf.rs +0 -149
- data/vendor/wreq/src/client/core/common/rewind.rs +0 -141
- data/vendor/wreq/src/client/core/common/watch.rs +0 -76
- data/vendor/wreq/src/client/core/common.rs +0 -3
- data/vendor/wreq/src/client/core/conn/http1.rs +0 -342
- data/vendor/wreq/src/client/core/conn/http2.rs +0 -307
- data/vendor/wreq/src/client/core/conn.rs +0 -11
- data/vendor/wreq/src/client/core/dispatch.rs +0 -299
- data/vendor/wreq/src/client/core/error.rs +0 -435
- data/vendor/wreq/src/client/core/ext.rs +0 -201
- data/vendor/wreq/src/client/core/http1.rs +0 -178
- data/vendor/wreq/src/client/core/http2.rs +0 -483
- data/vendor/wreq/src/client/core/proto/h1/conn.rs +0 -988
- data/vendor/wreq/src/client/core/proto/h1/decode.rs +0 -1170
- data/vendor/wreq/src/client/core/proto/h1/dispatch.rs +0 -684
- data/vendor/wreq/src/client/core/proto/h1/encode.rs +0 -580
- data/vendor/wreq/src/client/core/proto/h1/io.rs +0 -879
- data/vendor/wreq/src/client/core/proto/h1/role.rs +0 -694
- data/vendor/wreq/src/client/core/proto/h1.rs +0 -104
- data/vendor/wreq/src/client/core/proto/h2/client.rs +0 -650
- data/vendor/wreq/src/client/core/proto/h2/ping.rs +0 -539
- data/vendor/wreq/src/client/core/proto/h2.rs +0 -379
- data/vendor/wreq/src/client/core/proto/headers.rs +0 -138
- data/vendor/wreq/src/client/core/proto.rs +0 -58
- data/vendor/wreq/src/client/core/rt/bounds.rs +0 -57
- data/vendor/wreq/src/client/core/rt/timer.rs +0 -150
- data/vendor/wreq/src/client/core/rt/tokio.rs +0 -99
- data/vendor/wreq/src/client/core/rt.rs +0 -25
- data/vendor/wreq/src/client/core/upgrade.rs +0 -267
- data/vendor/wreq/src/client/core.rs +0 -16
- data/vendor/wreq/src/client/emulation.rs +0 -161
- data/vendor/wreq/src/client/http/client/error.rs +0 -142
- data/vendor/wreq/src/client/http/client/exec.rs +0 -29
- data/vendor/wreq/src/client/http/client/extra.rs +0 -77
- data/vendor/wreq/src/client/http/client/util.rs +0 -104
- data/vendor/wreq/src/client/http.rs +0 -1629
- data/vendor/wreq/src/client/layer/config/options.rs +0 -156
- data/vendor/wreq/src/client/layer/cookie.rs +0 -161
- data/vendor/wreq/src/hash.rs +0 -143
- data/vendor/wreq/src/tls/conn/cache.rs +0 -123
- data/vendor/wreq/src/tls/conn/cert_compression.rs +0 -125
- data/vendor/wreq/src/tls/keylog/handle.rs +0 -64
- data/vendor/wreq/src/tls/options.rs +0 -464
- /data/vendor/wreq/src/client/{http → layer}/client/lazy.rs +0 -0
- /data/vendor/wreq/src/{client/conn → conn}/proxy.rs +0 -0
- /data/vendor/wreq/src/{client/conn → conn}/verbose.rs +0 -0
data/ext/wreq_rb/src/client.rs
CHANGED
|
@@ -10,8 +10,10 @@ use magnus::{
|
|
|
10
10
|
};
|
|
11
11
|
use tokio::runtime::Runtime;
|
|
12
12
|
use tokio_util::sync::CancellationToken;
|
|
13
|
-
use
|
|
14
|
-
use
|
|
13
|
+
use std::net::IpAddr;
|
|
14
|
+
use wreq::header::{HeaderMap, HeaderName, HeaderValue, OrigHeaderMap};
|
|
15
|
+
use wreq::tls::TlsVersion;
|
|
16
|
+
use wreq_util::{Emulation as BrowserEmulation, Platform as EmulationPlatform, Profile as BrowserProfile};
|
|
15
17
|
|
|
16
18
|
use crate::error::{generic_error, to_magnus_error};
|
|
17
19
|
use crate::response::Response;
|
|
@@ -139,35 +141,35 @@ async fn execute_request(req: wreq::RequestBuilder) -> Result<ResponseData, wreq
|
|
|
139
141
|
// Emulation helpers
|
|
140
142
|
// --------------------------------------------------------------------------
|
|
141
143
|
|
|
142
|
-
/// The default
|
|
143
|
-
const DEFAULT_EMULATION:
|
|
144
|
+
/// The default browser profile to apply when none is specified.
|
|
145
|
+
const DEFAULT_EMULATION: BrowserProfile = BrowserProfile::Chrome148;
|
|
144
146
|
|
|
145
|
-
/// Parse a Ruby string like "chrome_143" into a
|
|
146
|
-
fn parse_emulation(name: &str) -> Result<
|
|
147
|
+
/// Parse a Ruby string like "chrome_143" into a BrowserProfile variant.
|
|
148
|
+
fn parse_emulation(name: &str) -> Result<BrowserProfile, magnus::Error> {
|
|
147
149
|
let json_val = serde_json::Value::String(name.to_string());
|
|
148
|
-
serde_json::from_value::<
|
|
149
|
-
.map_err(|_| generic_error(format!("unknown emulation: '{}'. Use names like '
|
|
150
|
+
serde_json::from_value::<BrowserProfile>(json_val)
|
|
151
|
+
.map_err(|_| generic_error(format!("unknown emulation: '{}'. Use names like 'chrome_148', 'firefox_151', 'safari_18.5', etc.", name)))
|
|
150
152
|
}
|
|
151
153
|
|
|
152
|
-
/// Parse a Ruby string like "windows" into an
|
|
153
|
-
fn parse_emulation_os(name: &str) -> Result<
|
|
154
|
+
/// Parse a Ruby string like "windows" into an EmulationPlatform variant.
|
|
155
|
+
fn parse_emulation_os(name: &str) -> Result<EmulationPlatform, magnus::Error> {
|
|
154
156
|
let json_val = serde_json::Value::String(name.to_string());
|
|
155
|
-
serde_json::from_value::<
|
|
157
|
+
serde_json::from_value::<EmulationPlatform>(json_val)
|
|
156
158
|
.map_err(|_| generic_error("unknown emulation_os. Use: 'windows', 'macos', 'linux', 'android', 'ios'"))
|
|
157
159
|
}
|
|
158
160
|
|
|
159
|
-
/// Build
|
|
161
|
+
/// Build a BrowserEmulation from a profile and an optional platform from the opts hash.
|
|
160
162
|
fn build_emulation_option(
|
|
161
|
-
|
|
163
|
+
profile: BrowserProfile,
|
|
162
164
|
opts: &RHash,
|
|
163
|
-
) -> Result<
|
|
164
|
-
let
|
|
165
|
-
Some(
|
|
166
|
-
None =>
|
|
165
|
+
) -> Result<BrowserEmulation, magnus::Error> {
|
|
166
|
+
let platform = match hash_get_string(opts, "emulation_os")? {
|
|
167
|
+
Some(platform_name) => parse_emulation_os(&platform_name)?,
|
|
168
|
+
None => EmulationPlatform::default(),
|
|
167
169
|
};
|
|
168
|
-
Ok(
|
|
169
|
-
.
|
|
170
|
-
.
|
|
170
|
+
Ok(BrowserEmulation::builder()
|
|
171
|
+
.profile(profile)
|
|
172
|
+
.platform(platform)
|
|
171
173
|
.build())
|
|
172
174
|
}
|
|
173
175
|
|
|
@@ -178,6 +180,7 @@ fn build_emulation_option(
|
|
|
178
180
|
#[magnus::wrap(class = "Wreq::Client", free_immediately)]
|
|
179
181
|
struct Client {
|
|
180
182
|
inner: wreq::Client,
|
|
183
|
+
cancel_token: std::sync::Mutex<CancellationToken>,
|
|
181
184
|
}
|
|
182
185
|
|
|
183
186
|
impl Client {
|
|
@@ -189,9 +192,16 @@ impl Client {
|
|
|
189
192
|
Some(RHash::try_convert(args[0])?)
|
|
190
193
|
};
|
|
191
194
|
|
|
192
|
-
let mut builder = wreq::Client::builder()
|
|
195
|
+
let mut builder = wreq::Client::builder()
|
|
196
|
+
.retry(wreq::retry::Policy::never());
|
|
193
197
|
|
|
194
198
|
if let Some(opts) = opts {
|
|
199
|
+
// Apply header_order BEFORE emulation so the user's ordering takes precedence
|
|
200
|
+
if let Some(ary) = hash_get_array(&opts, "header_order")? {
|
|
201
|
+
let orig = array_to_orig_header_map(ary)?;
|
|
202
|
+
builder = builder.orig_headers(orig);
|
|
203
|
+
}
|
|
204
|
+
|
|
195
205
|
if let Some(val) = hash_get_value(&opts, "emulation")? {
|
|
196
206
|
let ruby = unsafe { Ruby::get_unchecked() };
|
|
197
207
|
if val.is_kind_of(ruby.class_false_class()) {
|
|
@@ -267,11 +277,11 @@ impl Client {
|
|
|
267
277
|
}
|
|
268
278
|
|
|
269
279
|
if let Some(v) = hash_get_bool(&opts, "verify_host")? {
|
|
270
|
-
builder = builder.
|
|
280
|
+
builder = builder.tls_verify_hostname(v);
|
|
271
281
|
}
|
|
272
282
|
|
|
273
283
|
if let Some(v) = hash_get_bool(&opts, "verify_cert")? {
|
|
274
|
-
builder = builder.
|
|
284
|
+
builder = builder.tls_cert_verification(v);
|
|
275
285
|
}
|
|
276
286
|
|
|
277
287
|
if let Some(true) = hash_get_bool(&opts, "http1_only")? {
|
|
@@ -293,12 +303,50 @@ impl Client {
|
|
|
293
303
|
if let Some(v) = hash_get_bool(&opts, "zstd")? {
|
|
294
304
|
builder = builder.zstd(v);
|
|
295
305
|
}
|
|
306
|
+
|
|
307
|
+
if let Some(v) = hash_get_bool(&opts, "referer")? {
|
|
308
|
+
builder = builder.referer(v);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if let Some(n) = hash_get_usize(&opts, "pool_max_idle_per_host")? {
|
|
312
|
+
builder = builder.pool_max_idle_per_host(n);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if let Some(n) = hash_get_usize(&opts, "pool_max_size")? {
|
|
316
|
+
builder = builder.pool_max_size(n);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if let Some(v) = hash_get_bool(&opts, "tcp_nodelay")? {
|
|
320
|
+
builder = builder.tcp_nodelay(v);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if let Some(t) = hash_get_float(&opts, "tcp_keepalive")? {
|
|
324
|
+
builder = builder.tcp_keepalive(Duration::from_secs_f64(t));
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if let Some(addr_str) = hash_get_string(&opts, "local_address")? {
|
|
328
|
+
let addr: IpAddr = addr_str.parse()
|
|
329
|
+
.map_err(|_| generic_error(format!("invalid IP address: '{}'", addr_str)))?;
|
|
330
|
+
builder = builder.local_address(addr);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
if let Some(v) = hash_get_bool(&opts, "tls_sni")? {
|
|
334
|
+
builder = builder.tls_sni(v);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if let Some(s) = hash_get_string(&opts, "min_tls_version")? {
|
|
338
|
+
builder = builder.tls_min_version(parse_tls_version(&s)?);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if let Some(s) = hash_get_string(&opts, "max_tls_version")? {
|
|
342
|
+
builder = builder.tls_max_version(parse_tls_version(&s)?);
|
|
343
|
+
}
|
|
296
344
|
} else {
|
|
297
345
|
builder = builder.emulation(DEFAULT_EMULATION);
|
|
298
346
|
}
|
|
299
347
|
|
|
300
348
|
let client = builder.build().map_err(to_magnus_error)?;
|
|
301
|
-
Ok(Client { inner: client })
|
|
349
|
+
Ok(Client { inner: client, cancel_token: std::sync::Mutex::new(CancellationToken::new()) })
|
|
302
350
|
}
|
|
303
351
|
|
|
304
352
|
/// client.get(url) or client.get(url, opts)
|
|
@@ -330,6 +378,18 @@ impl Client {
|
|
|
330
378
|
self.execute_method("OPTIONS", args)
|
|
331
379
|
}
|
|
332
380
|
|
|
381
|
+
fn cancel(&self) {
|
|
382
|
+
// Replace the cancel token first so new requests use a fresh token,
|
|
383
|
+
// then cancel the old one to unblock all current in-flight select!s.
|
|
384
|
+
let old_token = {
|
|
385
|
+
let mut guard = self.cancel_token.lock().unwrap_or_else(|e| e.into_inner());
|
|
386
|
+
let old = guard.clone();
|
|
387
|
+
*guard = CancellationToken::new();
|
|
388
|
+
old
|
|
389
|
+
};
|
|
390
|
+
old_token.cancel();
|
|
391
|
+
}
|
|
392
|
+
|
|
333
393
|
fn execute_method(&self, method_str: &str, args: &[Value]) -> Result<Response, magnus::Error> {
|
|
334
394
|
let url: String = if args.is_empty() {
|
|
335
395
|
return Err(generic_error("url is required"));
|
|
@@ -353,13 +413,16 @@ impl Client {
|
|
|
353
413
|
req = apply_request_options(req, &opts)?;
|
|
354
414
|
}
|
|
355
415
|
|
|
416
|
+
let client_token = self.cancel_token.lock().unwrap_or_else(|e| e.into_inner()).clone();
|
|
417
|
+
|
|
356
418
|
// Release the GVL so other Ruby threads can run during I/O.
|
|
357
419
|
let outcome: RequestOutcome = unsafe {
|
|
358
|
-
without_gvl(|
|
|
420
|
+
without_gvl(|thread_token| {
|
|
359
421
|
runtime().block_on(async {
|
|
360
422
|
tokio::select! {
|
|
361
423
|
biased;
|
|
362
|
-
_ =
|
|
424
|
+
_ = thread_token.cancelled() => RequestOutcome::Interrupted,
|
|
425
|
+
_ = client_token.cancelled() => RequestOutcome::Interrupted,
|
|
363
426
|
res = execute_request(req) => match res {
|
|
364
427
|
Ok(data) => RequestOutcome::Ok(data),
|
|
365
428
|
Err(e) => RequestOutcome::Err(e),
|
|
@@ -382,6 +445,21 @@ fn apply_request_options(
|
|
|
382
445
|
mut req: wreq::RequestBuilder,
|
|
383
446
|
opts: &RHash,
|
|
384
447
|
) -> Result<wreq::RequestBuilder, magnus::Error> {
|
|
448
|
+
if let Some(val) = hash_get_value(opts, "emulation")? {
|
|
449
|
+
let ruby = unsafe { Ruby::get_unchecked() };
|
|
450
|
+
if val.is_kind_of(ruby.class_false_class()) {
|
|
451
|
+
// emulation: false — no per-request emulation override
|
|
452
|
+
} else if val.is_kind_of(ruby.class_true_class()) {
|
|
453
|
+
let opt = build_emulation_option(DEFAULT_EMULATION, opts)?;
|
|
454
|
+
req = req.emulation(opt);
|
|
455
|
+
} else {
|
|
456
|
+
let name: String = TryConvert::try_convert(val)?;
|
|
457
|
+
let emu = parse_emulation(&name)?;
|
|
458
|
+
let opt = build_emulation_option(emu, opts)?;
|
|
459
|
+
req = req.emulation(opt);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
385
463
|
if let Some(hdr_hash) = hash_get_hash(opts, "headers")? {
|
|
386
464
|
let hmap = hash_to_header_map(&hdr_hash)?;
|
|
387
465
|
req = req.headers(hmap);
|
|
@@ -436,21 +514,6 @@ fn apply_request_options(
|
|
|
436
514
|
req = req.proxy(proxy);
|
|
437
515
|
}
|
|
438
516
|
|
|
439
|
-
if let Some(val) = hash_get_value(opts, "emulation")? {
|
|
440
|
-
let ruby = unsafe { Ruby::get_unchecked() };
|
|
441
|
-
if val.is_kind_of(ruby.class_false_class()) {
|
|
442
|
-
// emulation: false — no per-request emulation override
|
|
443
|
-
} else if val.is_kind_of(ruby.class_true_class()) {
|
|
444
|
-
let opt = build_emulation_option(DEFAULT_EMULATION, opts)?;
|
|
445
|
-
req = req.emulation(opt);
|
|
446
|
-
} else {
|
|
447
|
-
let name: String = TryConvert::try_convert(val)?;
|
|
448
|
-
let emu = parse_emulation(&name)?;
|
|
449
|
-
let opt = build_emulation_option(emu, opts)?;
|
|
450
|
-
req = req.emulation(opt);
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
|
|
454
517
|
Ok(req)
|
|
455
518
|
}
|
|
456
519
|
|
|
@@ -529,6 +592,25 @@ fn hash_get_bool(hash: &RHash, key: &str) -> Result<Option<bool>, magnus::Error>
|
|
|
529
592
|
}
|
|
530
593
|
}
|
|
531
594
|
|
|
595
|
+
fn hash_get_usize(hash: &RHash, key: &str) -> Result<Option<usize>, magnus::Error> {
|
|
596
|
+
match hash_get_value(hash, key)? {
|
|
597
|
+
Some(v) => Ok(Some(TryConvert::try_convert(v)?)),
|
|
598
|
+
None => Ok(None),
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
fn parse_tls_version(s: &str) -> Result<TlsVersion, magnus::Error> {
|
|
603
|
+
match s {
|
|
604
|
+
"tls1.0" | "tls_1_0" | "1.0" => Ok(TlsVersion::TLS_1_0),
|
|
605
|
+
"tls1.1" | "tls_1_1" | "1.1" => Ok(TlsVersion::TLS_1_1),
|
|
606
|
+
"tls1.2" | "tls_1_2" | "1.2" => Ok(TlsVersion::TLS_1_2),
|
|
607
|
+
"tls1.3" | "tls_1_3" | "1.3" => Ok(TlsVersion::TLS_1_3),
|
|
608
|
+
_ => Err(generic_error(format!(
|
|
609
|
+
"unknown TLS version '{}'. Use: 'tls1.2', 'tls1.3'", s
|
|
610
|
+
))),
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
532
614
|
fn hash_get_hash(hash: &RHash, key: &str) -> Result<Option<RHash>, magnus::Error> {
|
|
533
615
|
match hash_get_value(hash, key)? {
|
|
534
616
|
Some(v) => Ok(Some(RHash::try_convert(v)?)),
|
|
@@ -536,6 +618,27 @@ fn hash_get_hash(hash: &RHash, key: &str) -> Result<Option<RHash>, magnus::Error
|
|
|
536
618
|
}
|
|
537
619
|
}
|
|
538
620
|
|
|
621
|
+
fn hash_get_array(hash: &RHash, key: &str) -> Result<Option<RArray>, magnus::Error> {
|
|
622
|
+
match hash_get_value(hash, key)? {
|
|
623
|
+
Some(v) => Ok(Some(RArray::try_convert(v)?)),
|
|
624
|
+
None => Ok(None),
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
fn array_to_orig_header_map(ary: RArray) -> Result<OrigHeaderMap, magnus::Error> {
|
|
629
|
+
let mut orig = OrigHeaderMap::with_capacity(ary.len());
|
|
630
|
+
for elem in ary.into_iter() {
|
|
631
|
+
let ruby = unsafe { Ruby::get_unchecked() };
|
|
632
|
+
let name_str: String = if elem.is_kind_of(ruby.class_symbol()) {
|
|
633
|
+
elem.funcall("to_s", ())?
|
|
634
|
+
} else {
|
|
635
|
+
TryConvert::try_convert(elem)?
|
|
636
|
+
};
|
|
637
|
+
orig.insert(name_str);
|
|
638
|
+
}
|
|
639
|
+
Ok(orig)
|
|
640
|
+
}
|
|
641
|
+
|
|
539
642
|
fn hash_to_header_map(hash: &RHash) -> Result<HeaderMap, magnus::Error> {
|
|
540
643
|
let mut hmap = HeaderMap::new();
|
|
541
644
|
hash.foreach(|k: Value, v: Value| {
|
|
@@ -589,6 +692,7 @@ pub fn init(_ruby: &magnus::Ruby, module: &magnus::RModule) -> Result<(), magnus
|
|
|
589
692
|
client_class.define_method("delete", method!(Client::delete, -1))?;
|
|
590
693
|
client_class.define_method("head", method!(Client::head, -1))?;
|
|
591
694
|
client_class.define_method("options", method!(Client::options, -1))?;
|
|
695
|
+
client_class.define_method("cancel", method!(Client::cancel, 0))?;
|
|
592
696
|
|
|
593
697
|
module.define_module_function("get", function!(wreq_get, -1))?;
|
|
594
698
|
module.define_module_function("post", function!(wreq_post, -1))?;
|
data/lib/wreq-rb/version.rb
CHANGED
|
@@ -1,60 +1,51 @@
|
|
|
1
|
-
diff --git a/src/client
|
|
2
|
-
index
|
|
3
|
-
--- a/src/client
|
|
4
|
-
+++ b/src/client
|
|
5
|
-
@@ -
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
+
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@@ -
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
+
|
|
1
|
+
diff --git a/src/client.rs b/src/client.rs
|
|
2
|
+
index 4abe25d8..76e709a8 100644
|
|
3
|
+
--- a/src/client.rs
|
|
4
|
+
+++ b/src/client.rs
|
|
5
|
+
@@ -49,6 +49,7 @@ use self::{
|
|
6
|
+
redirect::{FollowRedirect, FollowRedirectLayer},
|
|
7
|
+
retry::RetryPolicy,
|
|
8
|
+
timeout::{Timeout, TimeoutLayer, TimeoutOptions, body::TimeoutBody},
|
|
9
|
+
+ transfer_size::{CountingBody, TransferSizeLayer, TransferSizeService},
|
|
10
|
+
},
|
|
11
|
+
request::{Request, RequestBuilder},
|
|
12
|
+
response::Response,
|
|
13
|
+
@@ -115,25 +116,30 @@ type MaybeDecompressionBody<T> = tower_http::decompression::DecompressionBody<T>
|
|
14
|
+
type ClientService = Timeout<
|
|
15
|
+
ConfigService<
|
|
16
|
+
MaybeDecompression<
|
|
17
|
+
- Retry<RetryPolicy, FollowRedirect<HttpClient<Connector, Body>, FollowRedirectPolicy>>,
|
|
18
|
+
+ TransferSizeService<
|
|
19
|
+
+ Retry<
|
|
20
|
+
+ RetryPolicy,
|
|
21
|
+
+ FollowRedirect<HttpClient<Connector, Body>, FollowRedirectPolicy>,
|
|
22
|
+
+ >,
|
|
23
|
+
+ >,
|
|
24
|
+
>,
|
|
25
|
+
>,
|
|
26
|
+
>;
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
-type ResponseBody = TimeoutBody<Incoming>;
|
|
27
|
-
+type ResponseBody = TimeoutBody<CountingBody<Incoming>>;
|
|
28
|
+
type BoxedClientService = BoxCloneSyncService<
|
|
29
|
+
http::Request<Body>,
|
|
30
|
+
- http::Response<TimeoutBody<MaybeDecompressionBody<Incoming>>>,
|
|
31
|
+
+ http::Response<TimeoutBody<MaybeDecompressionBody<CountingBody<Incoming>>>>,
|
|
32
|
+
BoxError,
|
|
33
|
+
>;
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
+
|
|
43
|
-
+ RetryPolicy,
|
|
44
|
-
+ FollowRedirect<
|
|
45
|
-
+ CookieService<
|
|
46
|
-
+ MapErr<
|
|
47
|
-
+ HttpClient<Connector, Body>,
|
|
48
|
-
+ fn(client::error::Error) -> BoxError,
|
|
49
|
-
+ >,
|
|
50
|
-
>,
|
|
51
|
-
+ FollowRedirectPolicy,
|
|
52
|
-
>,
|
|
53
|
-
- FollowRedirectPolicy,
|
|
54
|
-
>,
|
|
55
|
-
>,
|
|
56
|
-
>,
|
|
57
|
-
@@ -582,6 +585,10 @@ impl ClientBuilder {
|
|
35
|
+
type BoxedClientServiceLayer = BoxCloneSyncServiceLayer<
|
|
36
|
+
BoxCloneSyncService<
|
|
37
|
+
http::Request<Body>,
|
|
38
|
+
- http::Response<MaybeDecompressionBody<Incoming>>,
|
|
39
|
+
+ http::Response<MaybeDecompressionBody<CountingBody<Incoming>>>,
|
|
40
|
+
BoxError,
|
|
41
|
+
>,
|
|
42
|
+
http::Request<Body>,
|
|
43
|
+
- http::Response<MaybeDecompressionBody<Incoming>>,
|
|
44
|
+
+ http::Response<MaybeDecompressionBody<CountingBody<Incoming>>>,
|
|
45
|
+
BoxError,
|
|
46
|
+
>;
|
|
47
|
+
|
|
48
|
+
@@ -593,6 +599,10 @@ impl ClientBuilder {
|
|
58
49
|
})
|
|
59
50
|
.service(service);
|
|
60
51
|
|
|
@@ -65,18 +56,36 @@ index 10be0c83..462c77d0 100644
|
|
|
65
56
|
#[cfg(any(
|
|
66
57
|
feature = "gzip",
|
|
67
58
|
feature = "zstd",
|
|
59
|
+
@@ -1585,7 +1595,7 @@ impl ClientBuilder {
|
|
60
|
+
L: Layer<
|
|
61
|
+
BoxCloneSyncService<
|
|
62
|
+
http::Request<Body>,
|
|
63
|
+
- http::Response<MaybeDecompressionBody<Incoming>>,
|
|
64
|
+
+ http::Response<MaybeDecompressionBody<CountingBody<Incoming>>>,
|
|
65
|
+
BoxError,
|
|
66
|
+
>,
|
|
67
|
+
> + Clone
|
|
68
|
+
@@ -1594,7 +1604,7 @@ impl ClientBuilder {
|
|
69
|
+
+ 'static,
|
|
70
|
+
L::Service: Service<
|
|
71
|
+
http::Request<Body>,
|
|
72
|
+
- Response = http::Response<MaybeDecompressionBody<Incoming>>,
|
|
73
|
+
+ Response = http::Response<MaybeDecompressionBody<CountingBody<Incoming>>>,
|
|
74
|
+
Error = BoxError,
|
|
75
|
+
> + Clone
|
|
76
|
+
+ Send
|
|
68
77
|
diff --git a/src/client/layer.rs b/src/client/layer.rs
|
|
69
|
-
index
|
|
78
|
+
index 5c03ef4d..fe37cff0 100644
|
|
70
79
|
--- a/src/client/layer.rs
|
|
71
80
|
+++ b/src/client/layer.rs
|
|
72
|
-
@@ -
|
|
81
|
+
@@ -12,3 +12,4 @@ pub mod decoder;
|
|
73
82
|
pub mod redirect;
|
|
74
83
|
pub mod retry;
|
|
75
84
|
pub mod timeout;
|
|
76
85
|
+pub mod transfer_size;
|
|
77
86
|
diff --git a/src/client/layer/transfer_size.rs b/src/client/layer/transfer_size.rs
|
|
78
87
|
new file mode 100644
|
|
79
|
-
index 00000000..
|
|
88
|
+
index 00000000..f155ec8d
|
|
80
89
|
--- /dev/null
|
|
81
90
|
+++ b/src/client/layer/transfer_size.rs
|
|
82
91
|
@@ -0,0 +1,176 @@
|
|
@@ -91,8 +100,8 @@ index 00000000..7e8a4390
|
|
|
91
100
|
+use std::{
|
|
92
101
|
+ pin::Pin,
|
|
93
102
|
+ sync::{
|
|
94
|
-
+ atomic::{AtomicU64, Ordering},
|
|
95
103
|
+ Arc,
|
|
104
|
+
+ atomic::{AtomicU64, Ordering},
|
|
96
105
|
+ },
|
|
97
106
|
+ task::{Context, Poll},
|
|
98
107
|
+};
|
|
@@ -257,18 +266,18 @@ index 00000000..7e8a4390
|
|
|
257
266
|
+ }
|
|
258
267
|
+}
|
|
259
268
|
diff --git a/src/client/response.rs b/src/client/response.rs
|
|
260
|
-
index
|
|
269
|
+
index 3d3532af..ed478804 100644
|
|
261
270
|
--- a/src/client/response.rs
|
|
262
271
|
+++ b/src/client/response.rs
|
|
263
|
-
@@ -
|
|
264
|
-
use
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
+
|
|
268
|
-
};
|
|
272
|
+
@@ -18,6 +18,7 @@ use mime::Mime;
|
|
273
|
+
use serde::de::DeserializeOwned;
|
|
274
|
+
use wreq_proto::ext::ReasonPhrase;
|
|
275
|
+
|
|
276
|
+
+use super::layer::transfer_size::TransferSizeHandle;
|
|
269
277
|
#[cfg(feature = "cookies")]
|
|
270
278
|
use crate::cookie;
|
|
271
|
-
|
|
279
|
+
use crate::{
|
|
280
|
+
@@ -97,6 +98,21 @@ impl Response {
|
|
272
281
|
HttpBody::size_hint(self.res.body()).exact()
|
|
273
282
|
}
|
|
274
283
|
|