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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +257 -102
  3. data/ext/wreq_rb/Cargo.toml +4 -4
  4. data/ext/wreq_rb/src/client.rs +1 -1
  5. data/lib/wreq-rb/version.rb +1 -1
  6. data/patches/0001-add-transfer-size-tracking.patch +11 -15
  7. data/vendor/wreq/Cargo.toml +9 -8
  8. data/vendor/wreq/README.md +5 -5
  9. data/vendor/wreq/bench/support/bench.rs +6 -2
  10. data/vendor/wreq/bench/support/client.rs +88 -1
  11. data/vendor/wreq/bench/support/exec.rs +0 -0
  12. data/vendor/wreq/bench/support/rt.rs +34 -0
  13. data/vendor/wreq/bench/support/server.rs +1 -1
  14. data/vendor/wreq/bench/support.rs +1 -15
  15. data/vendor/wreq/examples/cert_store.rs +13 -13
  16. data/vendor/wreq/examples/request_with_emulate.rs +1 -1
  17. data/vendor/wreq/examples/tcp_linger.rs +22 -0
  18. data/vendor/wreq/src/client/layer/client/pool.rs +17 -17
  19. data/vendor/wreq/src/client/layer/client.rs +2 -0
  20. data/vendor/wreq/src/client/layer/decoder.rs +71 -17
  21. data/vendor/wreq/src/client/layer/redirect/future.rs +49 -63
  22. data/vendor/wreq/src/client/layer/redirect/policy.rs +2 -26
  23. data/vendor/wreq/src/client/layer/redirect.rs +48 -60
  24. data/vendor/wreq/src/client/layer/retry.rs +12 -15
  25. data/vendor/wreq/src/client/layer/timeout/body.rs +27 -21
  26. data/vendor/wreq/src/client/layer/timeout/future.rs +33 -58
  27. data/vendor/wreq/src/client/layer/timeout.rs +8 -14
  28. data/vendor/wreq/src/client/request.rs +4 -0
  29. data/vendor/wreq/src/client.rs +53 -31
  30. data/vendor/wreq/src/conn/connector.rs +99 -129
  31. data/vendor/wreq/src/conn/http.rs +25 -18
  32. data/vendor/wreq/src/conn/net/tcp.rs +601 -107
  33. data/vendor/wreq/src/conn/proxy/socks.rs +6 -6
  34. data/vendor/wreq/src/conn/timeout.rs +166 -0
  35. data/vendor/wreq/src/conn.rs +5 -4
  36. data/vendor/wreq/src/cookie/jar.rs +1225 -0
  37. data/vendor/wreq/src/cookie/store.rs +321 -0
  38. data/vendor/wreq/src/cookie.rs +108 -612
  39. data/vendor/wreq/src/dns/resolve.rs +8 -2
  40. data/vendor/wreq/src/dns.rs +4 -4
  41. data/vendor/wreq/src/error.rs +53 -20
  42. data/vendor/wreq/src/lib.rs +1 -0
  43. data/vendor/wreq/src/proxy/matcher.rs +26 -12
  44. data/vendor/wreq/src/proxy/win.rs +39 -9
  45. data/vendor/wreq/src/redirect.rs +515 -100
  46. data/vendor/wreq/src/tls/conn.rs +3 -11
  47. data/vendor/wreq/src/tls/session.rs +7 -8
  48. data/vendor/wreq/src/tls/trust/store.rs +4 -4
  49. data/vendor/wreq/src/util.rs +23 -0
  50. data/vendor/wreq/tests/badssl.rs +72 -7
  51. data/vendor/wreq/tests/brotli.rs +1 -1
  52. data/vendor/wreq/tests/client.rs +24 -0
  53. data/vendor/wreq/tests/connector_layers.rs +8 -4
  54. data/vendor/wreq/tests/cookie.rs +59 -0
  55. data/vendor/wreq/tests/deflate.rs +1 -1
  56. data/vendor/wreq/tests/gzip.rs +53 -1
  57. data/vendor/wreq/tests/layers.rs +8 -4
  58. data/vendor/wreq/tests/redirect.rs +180 -97
  59. data/vendor/wreq/tests/timeouts.rs +47 -12
  60. data/vendor/wreq/tests/zstd.rs +1 -1
  61. metadata +7 -1
@@ -14,7 +14,7 @@ use tower::Service;
14
14
 
15
15
  use super::Tunneling;
16
16
  use crate::{
17
- dns::{GaiResolver, InternalResolve, Name},
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: InternalResolve + Clone,
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: InternalResolve + Clone + Send + 'static,
143
- <R as InternalResolve>::Future: Send + 'static,
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
+ }
@@ -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
- /// Boxed connector service for establishing connections.
44
- pub type BoxedConnectorService = BoxCloneSyncService<Unnameable, Conn, BoxError>;
44
+ /// Type-erased transport service retained after custom connector layers are composed.
45
+ pub type BoxedTransportConnector = BoxCloneSyncService<Unnameable, Conn, BoxError>;
45
46
 
46
- /// Boxed layer for building a boxed connector service.
47
+ /// Type-erased layer applied while assembling a [`BoxedTransportConnector`].
47
48
  pub type BoxedConnectorLayer =
48
- BoxCloneSyncServiceLayer<BoxedConnectorService, Unnameable, Conn, BoxError>;
49
+ BoxCloneSyncServiceLayer<BoxedTransportConnector, Unnameable, Conn, BoxError>;
49
50
 
50
51
  /// A wrapper type for [`descriptor::ConnectionDescriptor`] used to erase its concrete type.
51
52
  ///