wreq-rb 0.5.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.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +1922 -397
  3. data/LICENSE +203 -0
  4. data/README.md +19 -15
  5. data/ext/wreq_rb/Cargo.toml +4 -6
  6. data/ext/wreq_rb/src/client.rs +41 -48
  7. data/lib/wreq-rb/version.rb +1 -1
  8. data/patches/0001-add-transfer-size-tracking.patch +76 -67
  9. data/vendor/wreq/Cargo.toml +119 -71
  10. data/vendor/wreq/README.md +25 -20
  11. data/vendor/wreq/bench/http1.rs +25 -0
  12. data/vendor/wreq/bench/http1_over_tls.rs +25 -0
  13. data/vendor/wreq/bench/http2.rs +25 -0
  14. data/vendor/wreq/bench/http2_over_tls.rs +25 -0
  15. data/vendor/wreq/bench/support/bench.rs +91 -0
  16. data/vendor/wreq/bench/support/client.rs +217 -0
  17. data/vendor/wreq/bench/support/server.rs +188 -0
  18. data/vendor/wreq/bench/support.rs +56 -0
  19. data/vendor/wreq/examples/cert_store.rs +4 -4
  20. data/vendor/wreq/examples/{emulation.rs → emulate.rs} +2 -2
  21. data/vendor/wreq/examples/http2_websocket.rs +2 -2
  22. data/vendor/wreq/examples/keylog.rs +3 -3
  23. data/vendor/wreq/examples/{request_with_emulation.rs → request_with_emulate.rs} +2 -2
  24. data/vendor/wreq/examples/rt.rs +23 -0
  25. data/vendor/wreq/src/client/body.rs +23 -61
  26. data/vendor/wreq/src/client/emulate.rs +119 -0
  27. data/vendor/wreq/src/client/{http/future.rs → future.rs} +11 -32
  28. data/vendor/wreq/src/client/{http → layer}/client/pool.rs +66 -61
  29. data/vendor/wreq/src/client/{http → layer}/client.rs +416 -270
  30. data/vendor/wreq/src/client/layer/config.rs +27 -6
  31. data/vendor/wreq/src/client/layer/decoder.rs +9 -4
  32. data/vendor/wreq/src/client/layer/redirect/future.rs +6 -3
  33. data/vendor/wreq/src/client/layer/redirect.rs +4 -5
  34. data/vendor/wreq/src/client/layer/retry.rs +8 -5
  35. data/vendor/wreq/src/client/layer/timeout/body.rs +15 -6
  36. data/vendor/wreq/src/client/layer/timeout/future.rs +23 -18
  37. data/vendor/wreq/src/client/layer/timeout.rs +24 -74
  38. data/vendor/wreq/src/client/layer.rs +1 -2
  39. data/vendor/wreq/src/client/multipart.rs +137 -154
  40. data/vendor/wreq/src/client/request.rs +202 -118
  41. data/vendor/wreq/src/client/response.rs +46 -45
  42. data/vendor/wreq/src/client/upgrade.rs +15 -0
  43. data/vendor/wreq/src/client/ws.rs +73 -25
  44. data/vendor/wreq/src/client.rs +1655 -17
  45. data/vendor/wreq/src/config.rs +11 -11
  46. data/vendor/wreq/src/{client/conn → conn}/connector.rs +139 -137
  47. data/vendor/wreq/src/conn/descriptor.rs +143 -0
  48. data/vendor/wreq/src/conn/http.rs +484 -0
  49. data/vendor/wreq/src/conn/net/io.rs +75 -0
  50. data/vendor/wreq/src/conn/net/tcp/compio.rs +71 -0
  51. data/vendor/wreq/src/conn/net/tcp/tokio.rs +57 -0
  52. data/vendor/wreq/src/conn/net/tcp.rs +561 -0
  53. data/vendor/wreq/src/conn/net/uds/compio.rs +60 -0
  54. data/vendor/wreq/src/{client/conn/uds.rs → conn/net/uds/tokio.rs} +18 -12
  55. data/vendor/wreq/src/conn/net/uds.rs +11 -0
  56. data/vendor/wreq/src/conn/net.rs +130 -0
  57. data/vendor/wreq/src/{client/conn → conn}/proxy/socks.rs +2 -9
  58. data/vendor/wreq/src/{client/conn → conn}/proxy/tunnel.rs +21 -56
  59. data/vendor/wreq/src/conn/tls_info.rs +47 -0
  60. data/vendor/wreq/src/{client/conn.rs → conn.rs} +202 -54
  61. data/vendor/wreq/src/cookie.rs +302 -142
  62. data/vendor/wreq/src/dns/gai/compio.rs +77 -0
  63. data/vendor/wreq/src/dns/gai/tokio.rs +90 -0
  64. data/vendor/wreq/src/dns/gai.rs +14 -164
  65. data/vendor/wreq/src/dns/hickory.rs +16 -23
  66. data/vendor/wreq/src/dns/resolve.rs +7 -41
  67. data/vendor/wreq/src/dns.rs +90 -7
  68. data/vendor/wreq/src/error.rs +57 -31
  69. data/vendor/wreq/src/ext.rs +25 -0
  70. data/vendor/wreq/src/group.rs +211 -0
  71. data/vendor/wreq/src/header.rs +100 -112
  72. data/vendor/wreq/src/lib.rs +124 -73
  73. data/vendor/wreq/src/proxy.rs +6 -20
  74. data/vendor/wreq/src/redirect.rs +1 -1
  75. data/vendor/wreq/src/rt.rs +208 -0
  76. data/vendor/wreq/src/sync.rs +97 -98
  77. data/vendor/wreq/src/tls/compress.rs +124 -0
  78. data/vendor/wreq/src/tls/conn/ext.rs +54 -45
  79. data/vendor/wreq/src/tls/conn/service.rs +14 -18
  80. data/vendor/wreq/src/tls/conn.rs +169 -241
  81. data/vendor/wreq/src/tls/keylog.rs +68 -5
  82. data/vendor/wreq/src/tls/session.rs +205 -0
  83. data/vendor/wreq/src/tls/{x509 → trust}/identity.rs +4 -21
  84. data/vendor/wreq/src/tls/{x509/parser.rs → trust/parse.rs} +1 -1
  85. data/vendor/wreq/src/tls/{x509 → trust}/store.rs +42 -81
  86. data/vendor/wreq/src/tls/{x509.rs → trust.rs} +8 -2
  87. data/vendor/wreq/src/tls.rs +489 -25
  88. data/vendor/wreq/src/trace.rs +0 -12
  89. data/vendor/wreq/src/util.rs +1 -1
  90. data/vendor/wreq/tests/badssl.rs +10 -10
  91. data/vendor/wreq/tests/client.rs +3 -9
  92. data/vendor/wreq/tests/cookie.rs +6 -8
  93. data/vendor/wreq/tests/{emulation.rs → emulate.rs} +130 -22
  94. data/vendor/wreq/tests/multipart.rs +43 -1
  95. data/vendor/wreq/tests/proxy.rs +1 -1
  96. data/vendor/wreq/tests/support/layer.rs +1 -0
  97. metadata +49 -71
  98. data/patches/0002-add-cancel-connections.patch +0 -181
  99. data/vendor/wreq/src/client/conn/conn.rs +0 -231
  100. data/vendor/wreq/src/client/conn/http.rs +0 -1023
  101. data/vendor/wreq/src/client/conn/tls_info.rs +0 -98
  102. data/vendor/wreq/src/client/core/body/incoming.rs +0 -485
  103. data/vendor/wreq/src/client/core/body/length.rs +0 -118
  104. data/vendor/wreq/src/client/core/body.rs +0 -34
  105. data/vendor/wreq/src/client/core/common/buf.rs +0 -149
  106. data/vendor/wreq/src/client/core/common/rewind.rs +0 -141
  107. data/vendor/wreq/src/client/core/common/watch.rs +0 -76
  108. data/vendor/wreq/src/client/core/common.rs +0 -3
  109. data/vendor/wreq/src/client/core/conn/http1.rs +0 -342
  110. data/vendor/wreq/src/client/core/conn/http2.rs +0 -307
  111. data/vendor/wreq/src/client/core/conn.rs +0 -11
  112. data/vendor/wreq/src/client/core/dispatch.rs +0 -299
  113. data/vendor/wreq/src/client/core/error.rs +0 -435
  114. data/vendor/wreq/src/client/core/ext.rs +0 -201
  115. data/vendor/wreq/src/client/core/http1.rs +0 -178
  116. data/vendor/wreq/src/client/core/http2.rs +0 -483
  117. data/vendor/wreq/src/client/core/proto/h1/conn.rs +0 -988
  118. data/vendor/wreq/src/client/core/proto/h1/decode.rs +0 -1170
  119. data/vendor/wreq/src/client/core/proto/h1/dispatch.rs +0 -684
  120. data/vendor/wreq/src/client/core/proto/h1/encode.rs +0 -580
  121. data/vendor/wreq/src/client/core/proto/h1/io.rs +0 -879
  122. data/vendor/wreq/src/client/core/proto/h1/role.rs +0 -694
  123. data/vendor/wreq/src/client/core/proto/h1.rs +0 -104
  124. data/vendor/wreq/src/client/core/proto/h2/client.rs +0 -650
  125. data/vendor/wreq/src/client/core/proto/h2/ping.rs +0 -539
  126. data/vendor/wreq/src/client/core/proto/h2.rs +0 -379
  127. data/vendor/wreq/src/client/core/proto/headers.rs +0 -138
  128. data/vendor/wreq/src/client/core/proto.rs +0 -58
  129. data/vendor/wreq/src/client/core/rt/bounds.rs +0 -57
  130. data/vendor/wreq/src/client/core/rt/timer.rs +0 -150
  131. data/vendor/wreq/src/client/core/rt/tokio.rs +0 -99
  132. data/vendor/wreq/src/client/core/rt.rs +0 -25
  133. data/vendor/wreq/src/client/core/upgrade.rs +0 -267
  134. data/vendor/wreq/src/client/core.rs +0 -16
  135. data/vendor/wreq/src/client/emulation.rs +0 -161
  136. data/vendor/wreq/src/client/http/client/error.rs +0 -142
  137. data/vendor/wreq/src/client/http/client/exec.rs +0 -29
  138. data/vendor/wreq/src/client/http/client/extra.rs +0 -77
  139. data/vendor/wreq/src/client/http/client/util.rs +0 -104
  140. data/vendor/wreq/src/client/http.rs +0 -1629
  141. data/vendor/wreq/src/client/layer/config/options.rs +0 -156
  142. data/vendor/wreq/src/client/layer/cookie.rs +0 -161
  143. data/vendor/wreq/src/hash.rs +0 -143
  144. data/vendor/wreq/src/tls/conn/cache.rs +0 -123
  145. data/vendor/wreq/src/tls/conn/cert_compression.rs +0 -125
  146. data/vendor/wreq/src/tls/keylog/handle.rs +0 -64
  147. data/vendor/wreq/src/tls/options.rs +0 -464
  148. /data/vendor/wreq/src/client/{http → layer}/client/lazy.rs +0 -0
  149. /data/vendor/wreq/src/{client/conn → conn}/proxy.rs +0 -0
  150. /data/vendor/wreq/src/{client/conn → conn}/verbose.rs +0 -0
@@ -1,21 +1,36 @@
1
- mod options;
2
-
3
1
  use std::{
4
2
  sync::Arc,
5
3
  task::{Context, Poll},
6
4
  };
7
5
 
8
6
  use futures_util::future::{self, Either, Ready};
9
- use http::{HeaderMap, Request, Response};
7
+ use http::{HeaderMap, Request, Response, Version};
10
8
  use tower::{Layer, Service};
9
+ use wreq_proto::{http1::Http1Options, http2::Http2Options};
11
10
 
12
- pub use self::options::{RequestOptions, TransportOptions};
13
- use crate::{Error, config::RequestConfig, ext::UriExt, header::OrigHeaderMap};
11
+ use crate::{
12
+ Error, config::RequestConfig, conn::net::SocketBindOptions, ext::UriExt, group::Group,
13
+ header::OrigHeaderMap, proxy::Matcher, tls::TlsOptions,
14
+ };
14
15
 
15
16
  /// A marker type for the default headers configuration value.
16
17
  #[derive(Clone, Copy)]
17
18
  pub(crate) struct DefaultHeaders;
18
19
 
20
+ /// Per-request configuration for proxy, protocol, and transport options.
21
+ /// Overrides client defaults for a single request.
22
+ #[derive(Debug, Default, Clone)]
23
+ #[non_exhaustive]
24
+ pub(crate) struct RequestOptions {
25
+ pub group: Group,
26
+ pub proxy: Option<Matcher>,
27
+ pub version: Option<Version>,
28
+ pub tls_options: Option<TlsOptions>,
29
+ pub http1_options: Option<Http1Options>,
30
+ pub http2_options: Option<Http2Options>,
31
+ pub socket_bind_options: Option<SocketBindOptions>,
32
+ }
33
+
19
34
  /// Configuration for the [`ConfigService`].
20
35
  struct Config {
21
36
  https_only: bool,
@@ -40,6 +55,10 @@ pub struct ConfigService<S> {
40
55
 
41
56
  impl_request_config_value!(DefaultHeaders, bool);
42
57
 
58
+ // ===== impl RequestOptions =====
59
+
60
+ impl_request_config_value!(RequestOptions);
61
+
43
62
  // ===== impl ConfigServiceLayer =====
44
63
 
45
64
  impl ConfigServiceLayer {
@@ -109,7 +128,9 @@ where
109
128
  }
110
129
 
111
130
  // store the original headers in request extensions
112
- self.config.orig_headers.store(req.extensions_mut());
131
+ if let Some(orig_headers) = self.config.orig_headers.take(req.extensions_mut()) {
132
+ wreq_proto::ext::on_preserve_header(&mut req, orig_headers);
133
+ }
113
134
 
114
135
  Either::Left(self.inner.call(req))
115
136
  }
@@ -60,7 +60,7 @@ impl_request_config_value!(AcceptEncoding);
60
60
  impl DecompressionLayer {
61
61
  /// Creates a new [`DecompressionLayer`] with the specified [`AcceptEncoding`].
62
62
  #[inline(always)]
63
- pub const fn new(accept: AcceptEncoding) -> Self {
63
+ pub fn new(accept: AcceptEncoding) -> Self {
64
64
  Self { accept }
65
65
  }
66
66
  }
@@ -70,8 +70,13 @@ impl<S> Layer<S> for DecompressionLayer {
70
70
 
71
71
  #[inline(always)]
72
72
  fn layer(&self, service: S) -> Self::Service {
73
+ let decoder = decompression::Decompression::new(service)
74
+ .no_br()
75
+ .no_deflate()
76
+ .no_gzip()
77
+ .no_zstd();
73
78
  Decompression(Some(Decompression::<S>::accept_in_place(
74
- decompression::Decompression::new(service),
79
+ decoder,
75
80
  &self.accept,
76
81
  )))
77
82
  }
@@ -126,10 +131,10 @@ where
126
131
  }
127
132
 
128
133
  fn call(&mut self, req: Request<ReqBody>) -> Self::Future {
129
- if let Some(accept) = RequestConfig::<AcceptEncoding>::get(req.extensions()) {
134
+ if let Some(accept_encoding) = RequestConfig::<AcceptEncoding>::get(req.extensions()) {
130
135
  if let Some(decoder) = self.0.take() {
131
136
  self.0
132
- .replace(Decompression::accept_in_place(decoder, accept));
137
+ .replace(Decompression::accept_in_place(decoder, accept_encoding));
133
138
  }
134
139
  debug_assert!(self.0.is_some());
135
140
  }
@@ -13,11 +13,14 @@ use http::{
13
13
  };
14
14
  use http_body::Body;
15
15
  use pin_project_lite::pin_project;
16
- use tower::{Service, util::Oneshot};
16
+ use tower::{BoxError, Service, util::Oneshot};
17
17
  use url::Url;
18
18
 
19
- use super::{Action, Attempt, BodyRepr, Policy};
20
- use crate::{Error, error::BoxError, ext::RequestUri, into_uri::IntoUriSealed};
19
+ use super::{
20
+ BodyRepr,
21
+ policy::{Action, Attempt, Policy},
22
+ };
23
+ use crate::{Error, ext::RequestUri, into_uri::IntoUriSealed};
21
24
 
22
25
  /// Pending future state for handling redirects.
23
26
  pub struct Pending<ReqBody, Response> {
@@ -11,11 +11,10 @@ use std::{
11
11
  use futures_util::future::Either;
12
12
  use http::{Request, Response};
13
13
  use http_body::Body;
14
- use tower::{Layer, Service};
14
+ use tower::{BoxError, Layer, Service};
15
15
 
16
16
  use self::future::ResponseFuture;
17
17
  pub use self::policy::{Action, Attempt, Policy};
18
- use crate::error::BoxError;
19
18
 
20
19
  enum BodyRepr<B> {
21
20
  Some(B),
@@ -64,7 +63,7 @@ pub struct FollowRedirectLayer<P> {
64
63
  impl<P> FollowRedirectLayer<P> {
65
64
  /// Create a new [`FollowRedirectLayer`] with the given redirection [`Policy`].
66
65
  #[inline(always)]
67
- pub const fn with_policy(policy: P) -> Self {
66
+ pub fn with_policy(policy: P) -> Self {
68
67
  FollowRedirectLayer { policy }
69
68
  }
70
69
  }
@@ -95,7 +94,7 @@ where
95
94
  {
96
95
  /// Create a new [`FollowRedirect`] with the given redirection [`Policy`].
97
96
  #[inline(always)]
98
- pub const fn with_policy(inner: S, policy: P) -> Self {
97
+ pub fn with_policy(inner: S, policy: P) -> Self {
99
98
  FollowRedirect { inner, policy }
100
99
  }
101
100
  }
@@ -111,7 +110,7 @@ where
111
110
  type Error = S::Error;
112
111
  type Future = ResponseFuture<S, ReqBody, P>;
113
112
 
114
- #[inline]
113
+ #[inline(always)]
115
114
  fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
116
115
  self.inner.poll_ready(cx)
117
116
  }
@@ -6,17 +6,20 @@ mod scope;
6
6
  use std::{error::Error as StdError, future::Ready, sync::Arc, time::Duration};
7
7
 
8
8
  use http::{Request, Response};
9
- use tower::retry::{
10
- Policy,
11
- budget::{Budget, TpsBudget},
9
+ use tower::{
10
+ BoxError,
11
+ retry::{
12
+ Policy,
13
+ budget::{Budget, TpsBudget},
14
+ },
12
15
  };
16
+ use wreq_proto::body::Incoming;
13
17
 
14
18
  pub(crate) use self::{
15
19
  classify::{Action, Classifier, ClassifyFn, ReqRep},
16
20
  scope::{ScopeFn, Scoped},
17
21
  };
18
- use super::super::core::body::Incoming;
19
- use crate::{Body, error::BoxError, retry};
22
+ use crate::{Body, retry};
20
23
 
21
24
  /// A retry policy for HTTP requests.
22
25
  #[derive(Clone)]
@@ -7,11 +7,12 @@ use std::{
7
7
 
8
8
  use http_body::Body;
9
9
  use pin_project_lite::pin_project;
10
- use tokio::time::{Sleep, sleep};
10
+ use wreq_proto::rt::{Sleep, Timer as _};
11
11
 
12
12
  use crate::{
13
13
  Error,
14
14
  error::{BoxError, TimedOut},
15
+ rt::Timer,
15
16
  };
16
17
 
17
18
  pin_project! {
@@ -46,7 +47,7 @@ pin_project! {
46
47
  pub struct TotalTimeoutBody<B> {
47
48
  #[pin]
48
49
  body: B,
49
- timeout: Pin<Box<Sleep>>,
50
+ timeout: Pin<Box<dyn Sleep>>,
50
51
  }
51
52
  }
52
53
 
@@ -58,17 +59,23 @@ pin_project! {
58
59
  pub struct ReadTimeoutBody<B> {
59
60
  timeout: Duration,
60
61
  #[pin]
61
- sleep: Option<Sleep>,
62
+ sleep: Option<Pin<Box<dyn Sleep>>>,
62
63
  #[pin]
63
64
  body: B,
65
+ timer: Timer,
64
66
  }
65
67
  }
66
68
 
67
69
  /// ==== impl TimeoutBody ====
68
70
  impl<B> TimeoutBody<B> {
69
71
  /// Creates a new [`TimeoutBody`] with no timeout.
70
- pub fn new(deadline: Option<Duration>, read_timeout: Option<Duration>, body: B) -> Self {
71
- let deadline = deadline.map(sleep).map(Box::pin);
72
+ pub fn new(
73
+ timer: Timer,
74
+ deadline: Option<Duration>,
75
+ read_timeout: Option<Duration>,
76
+ body: B,
77
+ ) -> Self {
78
+ let deadline = deadline.map(|deadline| timer.sleep(deadline));
72
79
  match (deadline, read_timeout) {
73
80
  (Some(total_timeout), Some(read_timeout)) => TimeoutBody::CombinedTimeout {
74
81
  body: TotalTimeoutBody {
@@ -77,6 +84,7 @@ impl<B> TimeoutBody<B> {
77
84
  timeout: read_timeout,
78
85
  sleep: None,
79
86
  body,
87
+ timer,
80
88
  },
81
89
  },
82
90
  },
@@ -88,6 +96,7 @@ impl<B> TimeoutBody<B> {
88
96
  timeout,
89
97
  sleep: None,
90
98
  body,
99
+ timer,
91
100
  },
92
101
  },
93
102
  (None, None) => TimeoutBody::Plain { body },
@@ -199,7 +208,7 @@ where
199
208
 
200
209
  // Error if the timeout has expired.
201
210
  if this.sleep.is_none() {
202
- this.sleep.set(Some(sleep(*this.timeout)));
211
+ this.sleep.set(Some(this.timer.sleep(*this.timeout)));
203
212
  }
204
213
 
205
214
  // Error if the timeout has expired.
@@ -7,20 +7,21 @@ use std::{
7
7
 
8
8
  use http::Response;
9
9
  use pin_project_lite::pin_project;
10
- use tokio::time::Sleep;
10
+ use wreq_proto::rt::Sleep;
11
11
 
12
12
  use super::body::TimeoutBody;
13
- use crate::error::{BoxError, Error, TimedOut};
13
+ use crate::{
14
+ error::{BoxError, Error, TimedOut},
15
+ rt::Timer,
16
+ };
14
17
 
15
18
  pin_project! {
16
19
  /// [`Timeout`] response future
17
- pub struct ResponseFuture<F> {
18
- #[pin]
19
- pub(crate) response: F,
20
+ pub struct ResponseFuture<Fut> {
20
21
  #[pin]
21
- pub(crate) total_timeout: Option<Sleep>,
22
- #[pin]
23
- pub(crate) read_timeout: Option<Sleep>,
22
+ pub(crate) fut: Fut,
23
+ pub(crate) total_timeout: Option<Pin<Box<dyn Sleep>>>,
24
+ pub(crate) read_timeout: Option<Pin<Box<dyn Sleep>>>,
24
25
  }
25
26
  }
26
27
 
@@ -32,18 +33,18 @@ where
32
33
  type Output = Result<T, BoxError>;
33
34
 
34
35
  fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
35
- let mut this = self.project();
36
+ let this = self.project();
36
37
 
37
38
  // First, try polling the future
38
- match this.response.poll(cx) {
39
+ match this.fut.poll(cx) {
39
40
  Poll::Ready(v) => return Poll::Ready(v.map_err(Into::into)),
40
41
  Poll::Pending => {}
41
42
  }
42
43
 
43
44
  // Helper closure for polling a timeout and returning a TimedOut error
44
- let mut check_timeout = |sleep: Option<Pin<&mut Sleep>>| {
45
+ let mut check_timeout = |sleep: Option<&mut Pin<Box<dyn Sleep>>>| {
45
46
  if let Some(sleep) = sleep {
46
- if sleep.poll(cx).is_ready() {
47
+ if sleep.as_mut().poll(cx).is_ready() {
47
48
  return Some(Poll::Ready(Err(Error::request(TimedOut).into())));
48
49
  }
49
50
  }
@@ -51,12 +52,12 @@ where
51
52
  };
52
53
 
53
54
  // Check total timeout first
54
- if let Some(poll) = check_timeout(this.total_timeout.as_mut().as_pin_mut()) {
55
+ if let Some(poll) = check_timeout(this.total_timeout.as_mut()) {
55
56
  return poll;
56
57
  }
57
58
 
58
59
  // Check read timeout
59
- if let Some(poll) = check_timeout(this.read_timeout.as_mut().as_pin_mut()) {
60
+ if let Some(poll) = check_timeout(this.read_timeout.as_mut()) {
60
61
  return poll;
61
62
  }
62
63
 
@@ -65,12 +66,14 @@ where
65
66
  }
66
67
 
67
68
  pin_project! {
68
- /// Response future for [`ResponseBodyTimeout`].
69
+ /// Response future for wrapping the response body in [`TimeoutBody`].
69
70
  pub struct ResponseBodyTimeoutFuture<Fut> {
70
71
  #[pin]
71
- pub(super) inner: Fut,
72
+ pub(super) fut: Fut,
73
+ pub(super) timer: Timer,
72
74
  pub(super) total_timeout: Option<Duration>,
73
75
  pub(super) read_timeout: Option<Duration>,
76
+
74
77
  }
75
78
  }
76
79
 
@@ -80,11 +83,13 @@ where
80
83
  {
81
84
  type Output = Result<Response<TimeoutBody<ResBody>>, E>;
82
85
 
86
+ #[inline(always)]
83
87
  fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
88
+ let timer = self.timer.clone();
84
89
  let total_timeout = self.total_timeout;
85
90
  let read_timeout = self.read_timeout;
86
- let res = ready!(self.project().inner.poll(cx))?
87
- .map(|body| TimeoutBody::new(total_timeout, read_timeout, body));
91
+ let res = ready!(self.project().fut.poll(cx))?
92
+ .map(|body| TimeoutBody::new(timer, total_timeout, read_timeout, body));
88
93
  Poll::Ready(Ok(res))
89
94
  }
90
95
  }
@@ -1,6 +1,6 @@
1
1
  //! Middleware for setting a timeout on the response.
2
2
 
3
- mod body;
3
+ pub mod body;
4
4
  mod future;
5
5
 
6
6
  use std::{
@@ -9,11 +9,14 @@ use std::{
9
9
  };
10
10
 
11
11
  use http::{Request, Response};
12
- use tower::{Layer, Service};
12
+ use tower::{BoxError, Layer, Service};
13
+ use wreq_proto::rt::Timer as _;
13
14
 
14
- pub use self::body::TimeoutBody;
15
- use self::future::{ResponseBodyTimeoutFuture, ResponseFuture};
16
- use crate::{config::RequestConfig, error::BoxError};
15
+ use self::{
16
+ body::TimeoutBody,
17
+ future::{ResponseBodyTimeoutFuture, ResponseFuture},
18
+ };
19
+ use crate::{config::RequestConfig, rt::Timer};
17
20
 
18
21
  /// Options for configuring timeouts.
19
22
  #[derive(Clone, Copy, Default)]
@@ -44,14 +47,15 @@ impl_request_config_value!(TimeoutOptions);
44
47
  // This layer allows you to set a total timeout and a read timeout for requests.
45
48
  #[derive(Clone)]
46
49
  pub struct TimeoutLayer {
50
+ timer: Timer,
47
51
  timeout: RequestConfig<TimeoutOptions>,
48
52
  }
49
53
 
50
54
  impl TimeoutLayer {
51
55
  /// Create a new [`TimeoutLayer`].
52
- #[inline(always)]
53
- pub const fn new(options: TimeoutOptions) -> Self {
56
+ pub fn new(timer: Timer, options: TimeoutOptions) -> Self {
54
57
  TimeoutLayer {
58
+ timer,
55
59
  timeout: RequestConfig::new(Some(options)),
56
60
  }
57
61
  }
@@ -64,15 +68,17 @@ impl<S> Layer<S> for TimeoutLayer {
64
68
  fn layer(&self, service: S) -> Self::Service {
65
69
  Timeout {
66
70
  inner: service,
71
+ timer: self.timer.clone(),
67
72
  timeout: self.timeout,
68
73
  }
69
74
  }
70
75
  }
71
76
 
72
- /// Middleware that applies total and per-read timeouts to a [`Service`] response body.
77
+ /// Middleware that applies request and response-body timeouts to a [`Service`].
73
78
  #[derive(Clone)]
74
79
  pub struct Timeout<T> {
75
80
  inner: T,
81
+ timer: Timer,
76
82
  timeout: RequestConfig<TimeoutOptions>,
77
83
  }
78
84
 
@@ -80,9 +86,9 @@ impl<ReqBody, ResBody, S> Service<Request<ReqBody>> for Timeout<S>
80
86
  where
81
87
  S: Service<Request<ReqBody>, Response = Response<ResBody>, Error = BoxError>,
82
88
  {
83
- type Response = S::Response;
89
+ type Response = Response<TimeoutBody<ResBody>>;
84
90
  type Error = BoxError;
85
- type Future = ResponseFuture<S::Future>;
91
+ type Future = ResponseFuture<ResponseBodyTimeoutFuture<S::Future>>;
86
92
 
87
93
  #[inline(always)]
88
94
  fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
@@ -93,70 +99,14 @@ where
93
99
  fn call(&mut self, req: Request<ReqBody>) -> Self::Future {
94
100
  let (total_timeout, read_timeout) = fetch_timeout_options(&self.timeout, req.extensions());
95
101
  ResponseFuture {
96
- response: self.inner.call(req),
97
- total_timeout: total_timeout.map(tokio::time::sleep),
98
- read_timeout: read_timeout.map(tokio::time::sleep),
99
- }
100
- }
101
- }
102
-
103
- /// [`Layer`] that applies a [`ResponseBodyTimeout`] middleware to a service.
104
- // This layer allows you to set a total timeout and a read timeout for the response body.
105
- #[derive(Clone)]
106
- pub struct ResponseBodyTimeoutLayer {
107
- timeout: RequestConfig<TimeoutOptions>,
108
- }
109
-
110
- impl ResponseBodyTimeoutLayer {
111
- /// Creates a new [`ResponseBodyTimeoutLayer`].
112
- #[inline(always)]
113
- pub const fn new(options: TimeoutOptions) -> Self {
114
- Self {
115
- timeout: RequestConfig::new(Some(options)),
116
- }
117
- }
118
- }
119
-
120
- impl<S> Layer<S> for ResponseBodyTimeoutLayer {
121
- type Service = ResponseBodyTimeout<S>;
122
-
123
- #[inline(always)]
124
- fn layer(&self, inner: S) -> Self::Service {
125
- ResponseBodyTimeout {
126
- inner,
127
- timeout: self.timeout,
128
- }
129
- }
130
- }
131
-
132
- /// Middleware that timeouts the response body of a request with a [`Service`] to a total timeout
133
- /// and a read timeout.
134
- #[derive(Clone)]
135
- pub struct ResponseBodyTimeout<S> {
136
- inner: S,
137
- timeout: RequestConfig<TimeoutOptions>,
138
- }
139
-
140
- impl<S, ReqBody, ResBody> Service<Request<ReqBody>> for ResponseBodyTimeout<S>
141
- where
142
- S: Service<Request<ReqBody>, Response = Response<ResBody>>,
143
- {
144
- type Response = Response<TimeoutBody<ResBody>>;
145
- type Error = S::Error;
146
- type Future = ResponseBodyTimeoutFuture<S::Future>;
147
-
148
- #[inline(always)]
149
- fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
150
- self.inner.poll_ready(cx)
151
- }
152
-
153
- #[inline(always)]
154
- fn call(&mut self, req: Request<ReqBody>) -> Self::Future {
155
- let (total_timeout, read_timeout) = fetch_timeout_options(&self.timeout, req.extensions());
156
- ResponseBodyTimeoutFuture {
157
- inner: self.inner.call(req),
158
- total_timeout,
159
- read_timeout,
102
+ fut: ResponseBodyTimeoutFuture {
103
+ fut: self.inner.call(req),
104
+ timer: self.timer.clone(),
105
+ total_timeout,
106
+ read_timeout,
107
+ },
108
+ total_timeout: total_timeout.map(|timeout| self.timer.sleep(timeout)),
109
+ read_timeout: read_timeout.map(|timeout| self.timer.sleep(timeout)),
160
110
  }
161
111
  }
162
112
  }
@@ -1,8 +1,7 @@
1
1
  //! Middleware for the client.
2
2
 
3
+ pub mod client;
3
4
  pub mod config;
4
- #[cfg(feature = "cookies")]
5
- pub mod cookie;
6
5
  #[cfg(any(
7
6
  feature = "gzip",
8
7
  feature = "zstd",