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
@@ -100,9 +100,9 @@ async fn main() -> wreq::Result<()> {
100
100
  let emulation = Emulation::builder()
101
101
  .tls_options(tls)
102
102
  .http2_options(http2)
103
- .headers(headers)
104
103
  .orig_headers(orig_headers)
105
- .build();
104
+ .headers(headers)
105
+ .build(Default::default());
106
106
 
107
107
  // Use the API you're already familiar with
108
108
  let resp = wreq::get("https://tls.peet.ws/api/all")
@@ -0,0 +1,23 @@
1
+ use wreq::{Client, dns};
2
+ use wreq_rt::rt;
3
+
4
+ // Short example of a POST request with form data.
5
+ //
6
+ // This is using the `tokio` runtime. You'll need the following dependency:
7
+ //
8
+ // `tokio = { version = "1", features = ["full"] }`
9
+ #[compio::main]
10
+ async fn main() {
11
+ Client::builder()
12
+ .timer(rt::compio::CompioTimer::new())
13
+ .executor(rt::compio::CompioExecutor::new())
14
+ .dns_resolver(dns::GaiResolver::new())
15
+ .build()
16
+ .expect("build client");
17
+
18
+ let response = wreq::post("http://www.baidu.com")
19
+ .send()
20
+ .await
21
+ .expect("send");
22
+ println!("Response status {}", response.status());
23
+ }
@@ -5,16 +5,14 @@ use std::{
5
5
 
6
6
  use bytes::Bytes;
7
7
  use http_body::{Body as HttpBody, SizeHint};
8
- use http_body_util::{BodyExt, Either, combinators::BoxBody};
8
+ use http_body_util::{BodyExt, Either, Full, combinators::BoxBody};
9
9
  use pin_project_lite::pin_project;
10
- #[cfg(feature = "stream")]
11
- use {tokio::fs::File, tokio_util::io::ReaderStream};
12
10
 
13
11
  use crate::error::{BoxError, Error};
14
12
 
15
13
  /// An request body.
16
14
  #[derive(Debug)]
17
- pub struct Body(Either<Bytes, BoxBody<Bytes, BoxError>>);
15
+ pub struct Body(Either<Full<Bytes>, BoxBody<Bytes, BoxError>>);
18
16
 
19
17
  pin_project! {
20
18
  /// We can't use `map_frame()` because that loses the hint data (for good reason).
@@ -28,16 +26,6 @@ pin_project! {
28
26
  // ===== impl Body =====
29
27
 
30
28
  impl Body {
31
- /// Returns a reference to the internal data of the `Body`.
32
- ///
33
- /// `None` is returned, if the underlying data is a stream.
34
- pub fn as_bytes(&self) -> Option<&[u8]> {
35
- match &self.0 {
36
- Either::Left(bytes) => Some(bytes.as_ref()),
37
- Either::Right(..) => None,
38
- }
39
- }
40
-
41
29
  /// Wrap a [`HttpBody`] in a box inside `Body`.
42
30
  ///
43
31
  /// # Example
@@ -120,20 +108,19 @@ impl Body {
120
108
 
121
109
  #[inline]
122
110
  pub(crate) fn reusable(chunk: Bytes) -> Body {
123
- Body(Either::Left(chunk))
111
+ Body(Either::Left(Full::new(chunk)))
124
112
  }
125
113
 
114
+ #[inline]
126
115
  #[cfg(feature = "multipart")]
127
116
  pub(crate) fn content_length(&self) -> Option<u64> {
128
- match self.0 {
129
- Either::Left(ref bytes) => Some(bytes.len() as u64),
130
- Either::Right(ref body) => body.size_hint().exact(),
131
- }
117
+ self.0.size_hint().exact()
132
118
  }
133
119
 
120
+ #[inline]
134
121
  pub(crate) fn try_clone(&self) -> Option<Body> {
135
122
  match self.0 {
136
- Either::Left(ref chunk) => Some(Body::reusable(chunk.clone())),
123
+ Either::Left(ref chunk) => Some(Body(Either::Left(chunk.clone()))),
137
124
  Either::Right { .. } => None,
138
125
  }
139
126
  }
@@ -188,11 +175,11 @@ impl From<&'static str> for Body {
188
175
  }
189
176
  }
190
177
 
191
- #[cfg(feature = "stream")]
192
- impl From<File> for Body {
178
+ #[cfg(all(feature = "tokio-rt", feature = "stream"))]
179
+ impl From<tokio::fs::File> for Body {
193
180
  #[inline]
194
- fn from(file: File) -> Body {
195
- Body::wrap_stream(ReaderStream::new(file))
181
+ fn from(file: tokio::fs::File) -> Body {
182
+ Body::wrap_stream(tokio_util::io::ReaderStream::new(file))
196
183
  }
197
184
  }
198
185
 
@@ -200,44 +187,25 @@ impl HttpBody for Body {
200
187
  type Data = Bytes;
201
188
  type Error = Error;
202
189
 
190
+ #[inline(always)]
203
191
  fn poll_frame(
204
192
  mut self: Pin<&mut Self>,
205
193
  cx: &mut Context,
206
194
  ) -> Poll<Option<Result<http_body::Frame<Self::Data>, Self::Error>>> {
207
- match self.0 {
208
- Either::Left(ref mut bytes) => {
209
- let out = bytes.split_off(0);
210
- if out.is_empty() {
211
- Poll::Ready(None)
212
- } else {
213
- Poll::Ready(Some(Ok(http_body::Frame::data(out))))
214
- }
215
- }
216
- Either::Right(ref mut body) => {
217
- Poll::Ready(ready!(Pin::new(body).poll_frame(cx)).map(|opt_chunk| {
218
- opt_chunk.map_err(|err| match err.downcast::<Error>() {
219
- Ok(err) => *err,
220
- Err(err) => Error::body(err),
221
- })
222
- }))
223
- }
224
- }
195
+ Pin::new(&mut self.0).poll_frame(cx).map_err(|err| {
196
+ err.downcast::<Error>()
197
+ .map_or_else(Error::request, |err| *err)
198
+ })
225
199
  }
226
200
 
227
- #[inline]
201
+ #[inline(always)]
228
202
  fn size_hint(&self) -> SizeHint {
229
- match self.0 {
230
- Either::Left(ref bytes) => SizeHint::with_exact(bytes.len() as u64),
231
- Either::Right(ref body) => body.size_hint(),
232
- }
203
+ self.0.size_hint()
233
204
  }
234
205
 
235
- #[inline]
206
+ #[inline(always)]
236
207
  fn is_end_stream(&self) -> bool {
237
- match self.0 {
238
- Either::Left(ref bytes) => bytes.is_empty(),
239
- Either::Right(ref body) => body.is_end_stream(),
240
- }
208
+ self.0.is_end_stream()
241
209
  }
242
210
  }
243
211
 
@@ -251,6 +219,7 @@ where
251
219
  type Data = Bytes;
252
220
  type Error = B::Error;
253
221
 
222
+ #[inline(always)]
254
223
  fn poll_frame(
255
224
  self: Pin<&mut Self>,
256
225
  cx: &mut Context,
@@ -262,12 +231,12 @@ where
262
231
  }
263
232
  }
264
233
 
265
- #[inline]
234
+ #[inline(always)]
266
235
  fn size_hint(&self) -> SizeHint {
267
236
  self.inner.size_hint()
268
237
  }
269
238
 
270
- #[inline]
239
+ #[inline(always)]
271
240
  fn is_end_stream(&self) -> bool {
272
241
  self.inner.is_end_stream()
273
242
  }
@@ -279,13 +248,6 @@ mod tests {
279
248
 
280
249
  use super::Body;
281
250
 
282
- #[test]
283
- fn test_as_bytes() {
284
- let test_data = b"Test body";
285
- let body = Body::from(&test_data[..]);
286
- assert_eq!(body.as_bytes(), Some(&test_data[..]));
287
- }
288
-
289
251
  #[test]
290
252
  fn body_exact_length() {
291
253
  let empty_body = Body::empty();
@@ -0,0 +1,119 @@
1
+ use http::HeaderMap;
2
+ use wreq_proto::{http1::Http1Options, http2::Http2Options};
3
+
4
+ use crate::{group::Group, header::OrigHeaderMap, tls::TlsOptions};
5
+
6
+ /// Converts a value into an [`Emulation`] configuration.
7
+ ///
8
+ /// This trait lets multiple input types provide a unified way to produce
9
+ /// an emulation profile. Typical inputs include:
10
+ /// - Predefined browser profiles
11
+ /// - Transport option sets (e.g. HTTP/1, HTTP/2, TLS)
12
+ /// - User-defined strategy types
13
+ pub trait IntoEmulation {
14
+ /// Converts `self` into an [`Emulation`] configuration.
15
+ fn into_emulation(self) -> Emulation;
16
+ }
17
+
18
+ /// Builder for creating an [`Emulation`] configuration.
19
+ #[must_use]
20
+ #[derive(Debug)]
21
+ pub struct EmulationBuilder {
22
+ emulation: Emulation,
23
+ }
24
+
25
+ /// HTTP emulation settings for a client profile.
26
+ ///
27
+ /// Combines protocol options (HTTP/1, HTTP/2, TLS) and default headers.
28
+ #[non_exhaustive]
29
+ #[derive(Debug, Clone)]
30
+ pub struct Emulation {
31
+ pub(crate) group: Group,
32
+
33
+ /// Default headers applied to outgoing requests.
34
+ pub headers: HeaderMap,
35
+
36
+ /// Original headers with preserved case and duplicates.
37
+ pub orig_headers: OrigHeaderMap,
38
+
39
+ /// TLS configuration.
40
+ pub tls_options: Option<TlsOptions>,
41
+
42
+ /// HTTP/1 configuration.
43
+ pub http1_options: Option<Http1Options>,
44
+
45
+ /// HTTP/2 configuration.
46
+ pub http2_options: Option<Http2Options>,
47
+ }
48
+
49
+ // ==== impl EmulationBuilder ====
50
+
51
+ impl EmulationBuilder {
52
+ /// Sets the HTTP/1 options configuration.
53
+ #[inline]
54
+ pub fn http1_options(mut self, opts: Http1Options) -> Self {
55
+ self.emulation.http1_options = Some(opts);
56
+ self
57
+ }
58
+
59
+ /// Sets the HTTP/2 options configuration.
60
+ #[inline]
61
+ pub fn http2_options(mut self, opts: Http2Options) -> Self {
62
+ self.emulation.http2_options = Some(opts);
63
+ self
64
+ }
65
+
66
+ /// Sets the TLS options configuration.
67
+ #[inline]
68
+ pub fn tls_options(mut self, opts: TlsOptions) -> Self {
69
+ self.emulation.tls_options = Some(opts);
70
+ self
71
+ }
72
+
73
+ /// Sets the default headers.
74
+ #[inline]
75
+ pub fn headers(mut self, src: HeaderMap) -> Self {
76
+ crate::util::replace_headers(&mut self.emulation.headers, src);
77
+ self
78
+ }
79
+
80
+ /// Sets the original headers.
81
+ #[inline]
82
+ pub fn orig_headers(mut self, src: OrigHeaderMap) -> Self {
83
+ self.emulation.orig_headers.extend(src);
84
+ self
85
+ }
86
+
87
+ /// Builds the [`Emulation`] instance.
88
+ #[inline]
89
+ pub fn build(mut self, group: Group) -> Emulation {
90
+ self.emulation.group.emulate(group);
91
+ self.emulation
92
+ }
93
+ }
94
+
95
+ // ==== impl Emulation ====
96
+
97
+ impl Emulation {
98
+ /// Creates a new [`EmulationBuilder`].
99
+ #[inline]
100
+ pub fn builder() -> EmulationBuilder {
101
+ EmulationBuilder {
102
+ emulation: Emulation {
103
+ group: Group::default(),
104
+ headers: HeaderMap::new(),
105
+ orig_headers: OrigHeaderMap::new(),
106
+ tls_options: None,
107
+ http1_options: None,
108
+ http2_options: None,
109
+ },
110
+ }
111
+ }
112
+ }
113
+
114
+ impl<T: Into<Emulation>> IntoEmulation for T {
115
+ #[inline]
116
+ fn into_emulation(self) -> Emulation {
117
+ self.into()
118
+ }
119
+ }
@@ -5,12 +5,9 @@ use std::{
5
5
 
6
6
  use http::{Request, Uri};
7
7
  use pin_project_lite::pin_project;
8
- use tower::util::Oneshot;
8
+ use tower::util::{Either, Oneshot};
9
9
 
10
- use super::{Body, ClientRef, Response};
11
- use crate::{Error, ext::RequestUri};
12
-
13
- type ResponseFuture = Oneshot<ClientRef, Request<Body>>;
10
+ use super::{Body, BoxedClientService, ClientService, Error, Response};
14
11
 
15
12
  pin_project! {
16
13
  /// [`Pending`] is a future representing the state of an HTTP request, which may be either
@@ -19,8 +16,8 @@ pin_project! {
19
16
  #[project = PendingProj]
20
17
  pub enum Pending {
21
18
  Request {
22
- uri: Uri,
23
- fut: Pin<Box<ResponseFuture>>,
19
+ uri: Option<Uri>,
20
+ fut: Pin<Box<Oneshot<Either<ClientService, BoxedClientService>, Request<Body>>>>,
24
21
  },
25
22
  Error {
26
23
  error: Option<Error>,
@@ -28,23 +25,6 @@ pin_project! {
28
25
  }
29
26
  }
30
27
 
31
- impl Pending {
32
- /// Creates a new [`Pending`] with a request future and its associated URI.
33
- #[inline]
34
- pub(crate) fn request(uri: Uri, fut: ResponseFuture) -> Self {
35
- Pending::Request {
36
- uri,
37
- fut: Box::pin(fut),
38
- }
39
- }
40
-
41
- /// Creates a new [`Pending`] with an error.
42
- #[inline]
43
- pub(crate) fn error(error: Error) -> Self {
44
- Pending::Error { error: Some(error) }
45
- }
46
- }
47
-
48
28
  impl Future for Pending {
49
29
  type Output = Result<Response, Error>;
50
30
 
@@ -59,19 +39,18 @@ impl Future for Pending {
59
39
  }
60
40
  };
61
41
 
62
- let res = match ready!(res) {
63
- Ok(mut res) => {
64
- if let Some(redirect_uri) = res.extensions_mut().remove::<RequestUri>() {
65
- *uri = redirect_uri.0;
66
- }
67
- Ok(Response::new(res, uri.clone()))
68
- }
42
+ let res = ready!(res);
43
+ let uri = uri
44
+ .take()
45
+ .expect("Pending::Request polled after completion");
46
+ let res = match res {
47
+ Ok(res) => Ok(Response::new(res, uri)),
69
48
  Err(err) => {
70
49
  let mut err = err
71
50
  .downcast::<Error>()
72
51
  .map_or_else(Error::request, |err| *err);
73
52
  if err.uri().is_none() {
74
- err = err.with_uri(uri.clone());
53
+ err = err.with_uri(uri);
75
54
  }
76
55
  Err(err)
77
56
  }