wreq-rb 0.6.0 → 0.6.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 +257 -102
- data/ext/wreq_rb/Cargo.toml +4 -4
- data/ext/wreq_rb/src/client.rs +1 -1
- data/lib/wreq-rb/version.rb +1 -1
- data/patches/0001-add-transfer-size-tracking.patch +11 -15
- data/vendor/wreq/Cargo.toml +9 -8
- data/vendor/wreq/README.md +5 -5
- data/vendor/wreq/bench/support/bench.rs +6 -2
- data/vendor/wreq/bench/support/client.rs +88 -1
- data/vendor/wreq/bench/support/exec.rs +0 -0
- data/vendor/wreq/bench/support/rt.rs +34 -0
- data/vendor/wreq/bench/support/server.rs +1 -1
- data/vendor/wreq/bench/support.rs +1 -15
- data/vendor/wreq/examples/cert_store.rs +13 -13
- data/vendor/wreq/examples/request_with_emulate.rs +1 -1
- data/vendor/wreq/examples/tcp_linger.rs +22 -0
- data/vendor/wreq/src/client/layer/client/pool.rs +17 -17
- data/vendor/wreq/src/client/layer/client.rs +2 -0
- data/vendor/wreq/src/client/layer/decoder.rs +71 -17
- data/vendor/wreq/src/client/layer/redirect/future.rs +49 -63
- data/vendor/wreq/src/client/layer/redirect/policy.rs +2 -26
- data/vendor/wreq/src/client/layer/redirect.rs +48 -60
- data/vendor/wreq/src/client/layer/retry.rs +12 -15
- data/vendor/wreq/src/client/layer/timeout/body.rs +27 -21
- data/vendor/wreq/src/client/layer/timeout/future.rs +33 -58
- data/vendor/wreq/src/client/layer/timeout.rs +8 -14
- data/vendor/wreq/src/client/request.rs +4 -0
- data/vendor/wreq/src/client.rs +53 -31
- data/vendor/wreq/src/conn/connector.rs +99 -129
- data/vendor/wreq/src/conn/http.rs +25 -18
- data/vendor/wreq/src/conn/net/tcp.rs +601 -107
- data/vendor/wreq/src/conn/proxy/socks.rs +6 -6
- data/vendor/wreq/src/conn/timeout.rs +166 -0
- data/vendor/wreq/src/conn.rs +5 -4
- data/vendor/wreq/src/cookie/jar.rs +1225 -0
- data/vendor/wreq/src/cookie/store.rs +321 -0
- data/vendor/wreq/src/cookie.rs +108 -612
- data/vendor/wreq/src/dns/resolve.rs +8 -2
- data/vendor/wreq/src/dns.rs +4 -4
- data/vendor/wreq/src/error.rs +53 -20
- data/vendor/wreq/src/lib.rs +1 -0
- data/vendor/wreq/src/proxy/matcher.rs +26 -12
- data/vendor/wreq/src/proxy/win.rs +39 -9
- data/vendor/wreq/src/redirect.rs +515 -100
- data/vendor/wreq/src/tls/conn.rs +3 -11
- data/vendor/wreq/src/tls/session.rs +7 -8
- data/vendor/wreq/src/tls/trust/store.rs +4 -4
- data/vendor/wreq/src/util.rs +23 -0
- data/vendor/wreq/tests/badssl.rs +72 -7
- data/vendor/wreq/tests/brotli.rs +1 -1
- data/vendor/wreq/tests/client.rs +24 -0
- data/vendor/wreq/tests/connector_layers.rs +8 -4
- data/vendor/wreq/tests/cookie.rs +59 -0
- data/vendor/wreq/tests/deflate.rs +1 -1
- data/vendor/wreq/tests/gzip.rs +53 -1
- data/vendor/wreq/tests/layers.rs +8 -4
- data/vendor/wreq/tests/redirect.rs +180 -97
- data/vendor/wreq/tests/timeouts.rs +47 -12
- data/vendor/wreq/tests/zstd.rs +1 -1
- metadata +7 -1
|
@@ -14,7 +14,7 @@ use tower::Service;
|
|
|
14
14
|
|
|
15
15
|
use super::Tunneling;
|
|
16
16
|
use crate::{
|
|
17
|
-
dns::{GaiResolver,
|
|
17
|
+
dns::{DnsResolver, GaiResolver, Name, resolve},
|
|
18
18
|
error::BoxError,
|
|
19
19
|
ext::UriExt,
|
|
20
20
|
};
|
|
@@ -100,7 +100,7 @@ pub struct SocksConnector<C, R = GaiResolver> {
|
|
|
100
100
|
|
|
101
101
|
impl<C, R> SocksConnector<C, R>
|
|
102
102
|
where
|
|
103
|
-
R:
|
|
103
|
+
R: DnsResolver + Clone,
|
|
104
104
|
{
|
|
105
105
|
/// Create a new [`SocksConnector`].
|
|
106
106
|
pub fn new(proxy_dst: Uri, inner: C, resolver: R) -> Self {
|
|
@@ -139,8 +139,8 @@ where
|
|
|
139
139
|
C::Future: Send + 'static,
|
|
140
140
|
C::Response: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
|
141
141
|
C::Error: Into<BoxError>,
|
|
142
|
-
R:
|
|
143
|
-
|
|
142
|
+
R: DnsResolver + Clone + Send + 'static,
|
|
143
|
+
R::Future: Send + 'static,
|
|
144
144
|
{
|
|
145
145
|
type Response = C::Response;
|
|
146
146
|
type Error = SocksError;
|
|
@@ -164,6 +164,7 @@ where
|
|
|
164
164
|
|
|
165
165
|
let fut = async move {
|
|
166
166
|
let host = dst.host().ok_or(SocksError::MissingHost)?;
|
|
167
|
+
let host = crate::util::strip_ipv6_brackets(host);
|
|
167
168
|
let port = dst.port_or_default();
|
|
168
169
|
|
|
169
170
|
// Attempt to tcp connect to the proxy server.
|
|
@@ -176,8 +177,7 @@ where
|
|
|
176
177
|
// Resolve the target address using the provided resolver.
|
|
177
178
|
let target_addr = match dns_resolve {
|
|
178
179
|
DnsResolve::Local => {
|
|
179
|
-
let mut socket_addr = resolver
|
|
180
|
-
.resolve(Name::new(host.into()))
|
|
180
|
+
let mut socket_addr = resolve(&mut resolver, Name::new(host.into()))
|
|
181
181
|
.await
|
|
182
182
|
.map(|mut s| s.next())
|
|
183
183
|
.transpose()
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
//! Runtime-neutral timeout middleware for connector services.
|
|
2
|
+
|
|
3
|
+
use std::{
|
|
4
|
+
future::Future,
|
|
5
|
+
pin::Pin,
|
|
6
|
+
task::{Context, Poll},
|
|
7
|
+
time::Duration,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
use pin_project_lite::pin_project;
|
|
11
|
+
use tower::{BoxError, Layer, Service};
|
|
12
|
+
use wreq_proto::rt::{Sleep, Timer as _};
|
|
13
|
+
|
|
14
|
+
use crate::{error::TimedOut, rt::Timer};
|
|
15
|
+
|
|
16
|
+
/// Captures timeout configuration while the connector service graph is assembled.
|
|
17
|
+
///
|
|
18
|
+
/// Applying this layer transfers the client timer and optional duration into [`Timeout`]; it does
|
|
19
|
+
/// not start a timer until a connection attempt begins.
|
|
20
|
+
#[derive(Clone)]
|
|
21
|
+
pub(super) struct TimeoutLayer {
|
|
22
|
+
timer: Timer,
|
|
23
|
+
timeout: Option<Duration>,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/// Wraps a connector service with a deadline for each connection attempt.
|
|
27
|
+
///
|
|
28
|
+
/// This service remains in the client graph and creates a separate [`TimeoutFuture`] on every
|
|
29
|
+
/// call, so concurrent attempts do not share timeout state.
|
|
30
|
+
#[derive(Clone)]
|
|
31
|
+
pub struct Timeout<S> {
|
|
32
|
+
inner: S,
|
|
33
|
+
timer: Timer,
|
|
34
|
+
timeout: Option<Duration>,
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
pin_project! {
|
|
38
|
+
/// Owns one in-flight connection and its optional timeout sleep.
|
|
39
|
+
///
|
|
40
|
+
/// The connection is polled first; while it remains pending, the sleep can end the attempt.
|
|
41
|
+
/// Dropping this future drops both operations.
|
|
42
|
+
pub struct TimeoutFuture<F> {
|
|
43
|
+
#[pin]
|
|
44
|
+
future: F,
|
|
45
|
+
sleep: Option<Pin<Box<dyn Sleep>>>,
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// ===== impl TimeoutLayer =====
|
|
50
|
+
|
|
51
|
+
impl TimeoutLayer {
|
|
52
|
+
pub(super) fn new(timer: Timer, timeout: Option<Duration>) -> Self {
|
|
53
|
+
Self { timer, timeout }
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
impl<S> Layer<S> for TimeoutLayer {
|
|
58
|
+
type Service = Timeout<S>;
|
|
59
|
+
|
|
60
|
+
fn layer(&self, inner: S) -> Self::Service {
|
|
61
|
+
Timeout {
|
|
62
|
+
inner,
|
|
63
|
+
timer: self.timer.clone(),
|
|
64
|
+
timeout: self.timeout,
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ===== impl Timeout =====
|
|
70
|
+
|
|
71
|
+
impl<S, Request> Service<Request> for Timeout<S>
|
|
72
|
+
where
|
|
73
|
+
S: Service<Request>,
|
|
74
|
+
S::Error: Into<BoxError>,
|
|
75
|
+
{
|
|
76
|
+
type Response = S::Response;
|
|
77
|
+
type Error = BoxError;
|
|
78
|
+
type Future = TimeoutFuture<S::Future>;
|
|
79
|
+
|
|
80
|
+
#[inline]
|
|
81
|
+
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
82
|
+
self.inner.poll_ready(cx).map_err(Into::into)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
fn call(&mut self, request: Request) -> Self::Future {
|
|
86
|
+
let future = self.inner.call(request);
|
|
87
|
+
let sleep = self.timeout.map(|timeout| self.timer.sleep(timeout));
|
|
88
|
+
TimeoutFuture { future, sleep }
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ===== impl TimeoutFuture =====
|
|
93
|
+
|
|
94
|
+
impl<F, T, E> Future for TimeoutFuture<F>
|
|
95
|
+
where
|
|
96
|
+
F: Future<Output = Result<T, E>>,
|
|
97
|
+
E: Into<BoxError>,
|
|
98
|
+
{
|
|
99
|
+
type Output = Result<T, BoxError>;
|
|
100
|
+
|
|
101
|
+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
102
|
+
let this = self.project();
|
|
103
|
+
|
|
104
|
+
match this.future.poll(cx) {
|
|
105
|
+
Poll::Ready(result) => return Poll::Ready(result.map_err(Into::into)),
|
|
106
|
+
Poll::Pending => {}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if let Some(sleep) = this.sleep.as_mut()
|
|
110
|
+
&& sleep.as_mut().poll(cx).is_ready()
|
|
111
|
+
{
|
|
112
|
+
return Poll::Ready(Err(Box::new(TimedOut)));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
Poll::Pending
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
#[cfg(test)]
|
|
120
|
+
mod tests {
|
|
121
|
+
use std::{future::pending, task::Waker, time::Instant};
|
|
122
|
+
|
|
123
|
+
use super::*;
|
|
124
|
+
|
|
125
|
+
#[derive(Clone)]
|
|
126
|
+
struct ReadyTimer;
|
|
127
|
+
|
|
128
|
+
struct ReadySleep;
|
|
129
|
+
|
|
130
|
+
impl wreq_proto::rt::Timer for ReadyTimer {
|
|
131
|
+
fn sleep(&self, _duration: Duration) -> Pin<Box<dyn Sleep>> {
|
|
132
|
+
Box::pin(ReadySleep)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
fn sleep_until(&self, _deadline: Instant) -> Pin<Box<dyn Sleep>> {
|
|
136
|
+
self.sleep(Duration::ZERO)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
impl Future for ReadySleep {
|
|
141
|
+
type Output = ();
|
|
142
|
+
|
|
143
|
+
fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
144
|
+
Poll::Ready(())
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
impl Sleep for ReadySleep {
|
|
149
|
+
fn reset(self: Pin<&mut Self>, _new_deadline: Instant) {}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
#[test]
|
|
153
|
+
fn connect_timeout_uses_configured_timer_without_runtime() {
|
|
154
|
+
let mut service =
|
|
155
|
+
TimeoutLayer::new(Timer::new(ReadyTimer), Some(Duration::from_millis(50)))
|
|
156
|
+
.layer(tower::service_fn(|()| pending::<Result<(), BoxError>>()));
|
|
157
|
+
|
|
158
|
+
let mut future = Box::pin(service.call(()));
|
|
159
|
+
let mut cx = Context::from_waker(Waker::noop());
|
|
160
|
+
let Poll::Ready(Err(error)) = future.as_mut().poll(&mut cx) else {
|
|
161
|
+
panic!("connect timeout did not complete");
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
assert!(error.is::<TimedOut>());
|
|
165
|
+
}
|
|
166
|
+
}
|
data/vendor/wreq/src/conn.rs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
mod timeout;
|
|
1
2
|
mod tls_info;
|
|
2
3
|
mod verbose;
|
|
3
4
|
|
|
@@ -40,12 +41,12 @@ use crate::{
|
|
|
40
41
|
/// HTTP connector with dynamic DNS resolver.
|
|
41
42
|
pub type HttpConnector = http::HttpConnector<DynResolver, TcpConnector>;
|
|
42
43
|
|
|
43
|
-
///
|
|
44
|
-
pub type
|
|
44
|
+
/// Type-erased transport service retained after custom connector layers are composed.
|
|
45
|
+
pub type BoxedTransportConnector = BoxCloneSyncService<Unnameable, Conn, BoxError>;
|
|
45
46
|
|
|
46
|
-
///
|
|
47
|
+
/// Type-erased layer applied while assembling a [`BoxedTransportConnector`].
|
|
47
48
|
pub type BoxedConnectorLayer =
|
|
48
|
-
BoxCloneSyncServiceLayer<
|
|
49
|
+
BoxCloneSyncServiceLayer<BoxedTransportConnector, Unnameable, Conn, BoxError>;
|
|
49
50
|
|
|
50
51
|
/// A wrapper type for [`descriptor::ConnectionDescriptor`] used to erase its concrete type.
|
|
51
52
|
///
|