wreq-rb 0.6.0 → 0.6.2
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 +7 -4
- data/ext/wreq_rb/src/client.rs +105 -15
- data/ext/wreq_rb/src/response.rs +28 -3
- 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 +8 -2
|
@@ -3,7 +3,7 @@ use http::StatusCode;
|
|
|
3
3
|
use http_body_util::BodyExt;
|
|
4
4
|
use support::server;
|
|
5
5
|
use wreq::{
|
|
6
|
-
Body, Client,
|
|
6
|
+
Body, Client, header,
|
|
7
7
|
redirect::{History, Policy},
|
|
8
8
|
};
|
|
9
9
|
|
|
@@ -17,15 +17,15 @@ async fn test_redirect_301_and_302_and_303_changes_post_to_get() {
|
|
|
17
17
|
assert_eq!(req.uri(), &*format!("/{code}"));
|
|
18
18
|
http::Response::builder()
|
|
19
19
|
.status(code)
|
|
20
|
-
.header(
|
|
21
|
-
.header(
|
|
20
|
+
.header(header::LOCATION, "/dst")
|
|
21
|
+
.header(header::SERVER, "test-redirect")
|
|
22
22
|
.body(Body::default())
|
|
23
23
|
.unwrap()
|
|
24
24
|
} else {
|
|
25
25
|
assert_eq!(req.method(), "GET");
|
|
26
26
|
|
|
27
27
|
http::Response::builder()
|
|
28
|
-
.header(
|
|
28
|
+
.header(header::SERVER, "test-dst")
|
|
29
29
|
.body(Body::default())
|
|
30
30
|
.unwrap()
|
|
31
31
|
}
|
|
@@ -40,10 +40,7 @@ async fn test_redirect_301_and_302_and_303_changes_post_to_get() {
|
|
|
40
40
|
.unwrap();
|
|
41
41
|
assert_eq!(res.uri(), dst.as_str());
|
|
42
42
|
assert_eq!(res.status(), wreq::StatusCode::OK);
|
|
43
|
-
assert_eq!(
|
|
44
|
-
res.headers().get(wreq::header::SERVER).unwrap(),
|
|
45
|
-
&"test-dst"
|
|
46
|
-
);
|
|
43
|
+
assert_eq!(res.headers().get(header::SERVER).unwrap(), &"test-dst");
|
|
47
44
|
}
|
|
48
45
|
}
|
|
49
46
|
|
|
@@ -56,15 +53,15 @@ async fn test_redirect_307_and_308_tries_to_get_again() {
|
|
|
56
53
|
if req.uri() == &*format!("/{code}") {
|
|
57
54
|
http::Response::builder()
|
|
58
55
|
.status(code)
|
|
59
|
-
.header(
|
|
60
|
-
.header(
|
|
56
|
+
.header(header::LOCATION, "/dst")
|
|
57
|
+
.header(header::SERVER, "test-redirect")
|
|
61
58
|
.body(Body::default())
|
|
62
59
|
.unwrap()
|
|
63
60
|
} else {
|
|
64
61
|
assert_eq!(req.uri(), "/dst");
|
|
65
62
|
|
|
66
63
|
http::Response::builder()
|
|
67
|
-
.header(
|
|
64
|
+
.header(header::SERVER, "test-dst")
|
|
68
65
|
.body(Body::default())
|
|
69
66
|
.unwrap()
|
|
70
67
|
}
|
|
@@ -79,10 +76,7 @@ async fn test_redirect_307_and_308_tries_to_get_again() {
|
|
|
79
76
|
.unwrap();
|
|
80
77
|
assert_eq!(res.uri(), dst.as_str());
|
|
81
78
|
assert_eq!(res.status(), wreq::StatusCode::OK);
|
|
82
|
-
assert_eq!(
|
|
83
|
-
res.headers().get(wreq::header::SERVER).unwrap(),
|
|
84
|
-
&"test-dst"
|
|
85
|
-
);
|
|
79
|
+
assert_eq!(res.headers().get(header::SERVER).unwrap(), &"test-dst");
|
|
86
80
|
}
|
|
87
81
|
}
|
|
88
82
|
|
|
@@ -94,7 +88,7 @@ async fn test_redirect_307_and_308_tries_to_post_again() {
|
|
|
94
88
|
for &code in &codes {
|
|
95
89
|
let redirect = server::http(move |mut req| async move {
|
|
96
90
|
assert_eq!(req.method(), "POST");
|
|
97
|
-
assert_eq!(req.headers()[
|
|
91
|
+
assert_eq!(req.headers()[header::CONTENT_LENGTH], "5");
|
|
98
92
|
|
|
99
93
|
let data = req
|
|
100
94
|
.body_mut()
|
|
@@ -109,15 +103,15 @@ async fn test_redirect_307_and_308_tries_to_post_again() {
|
|
|
109
103
|
if req.uri() == &*format!("/{code}") {
|
|
110
104
|
http::Response::builder()
|
|
111
105
|
.status(code)
|
|
112
|
-
.header(
|
|
113
|
-
.header(
|
|
106
|
+
.header(header::LOCATION, "/dst")
|
|
107
|
+
.header(header::SERVER, "test-redirect")
|
|
114
108
|
.body(Body::default())
|
|
115
109
|
.unwrap()
|
|
116
110
|
} else {
|
|
117
111
|
assert_eq!(req.uri(), "/dst");
|
|
118
112
|
|
|
119
113
|
http::Response::builder()
|
|
120
|
-
.header(
|
|
114
|
+
.header(header::SERVER, "test-dst")
|
|
121
115
|
.body(Body::default())
|
|
122
116
|
.unwrap()
|
|
123
117
|
}
|
|
@@ -133,59 +127,147 @@ async fn test_redirect_307_and_308_tries_to_post_again() {
|
|
|
133
127
|
.unwrap();
|
|
134
128
|
assert_eq!(res.uri(), dst.as_str());
|
|
135
129
|
assert_eq!(res.status(), wreq::StatusCode::OK);
|
|
136
|
-
assert_eq!(
|
|
137
|
-
res.headers().get(wreq::header::SERVER).unwrap(),
|
|
138
|
-
&"test-dst"
|
|
139
|
-
);
|
|
130
|
+
assert_eq!(res.headers().get(header::SERVER).unwrap(), &"test-dst");
|
|
140
131
|
}
|
|
141
132
|
}
|
|
142
133
|
|
|
143
134
|
#[tokio::test]
|
|
144
135
|
async fn test_redirect_removes_sensitive_headers() {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
)
|
|
160
|
-
http::Response::default()
|
|
136
|
+
let end_server = server::http(move |req| async move {
|
|
137
|
+
match req.uri().path() {
|
|
138
|
+
"/middle" => {
|
|
139
|
+
assert_eq!(req.headers().get(header::COOKIE), None);
|
|
140
|
+
http::Response::builder()
|
|
141
|
+
.status(302)
|
|
142
|
+
.header(header::LOCATION, "/end")
|
|
143
|
+
.body(Body::default())
|
|
144
|
+
.unwrap()
|
|
145
|
+
}
|
|
146
|
+
"/end" => {
|
|
147
|
+
assert_eq!(req.headers().get(header::COOKIE), None);
|
|
148
|
+
http::Response::default()
|
|
149
|
+
}
|
|
150
|
+
path => panic!("unexpected redirect path: {path}"),
|
|
161
151
|
}
|
|
162
152
|
});
|
|
163
153
|
|
|
164
154
|
let end_addr = end_server.addr();
|
|
165
155
|
|
|
166
|
-
let
|
|
167
|
-
assert_eq!(req.headers()[
|
|
156
|
+
let start_server = server::http(move |req| async move {
|
|
157
|
+
assert_eq!(req.headers()[header::COOKIE], "foo=bar");
|
|
168
158
|
http::Response::builder()
|
|
169
159
|
.status(302)
|
|
170
|
-
.header(
|
|
160
|
+
.header(header::LOCATION, format!("http://{end_addr}/middle"))
|
|
171
161
|
.body(Body::default())
|
|
172
162
|
.unwrap()
|
|
173
163
|
});
|
|
174
164
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
Client::builder()
|
|
165
|
+
let response = Client::builder()
|
|
178
166
|
.redirect(Policy::default())
|
|
179
167
|
.build()
|
|
180
168
|
.unwrap()
|
|
181
|
-
.get(format!("http://{}/sensitive",
|
|
182
|
-
.header(
|
|
183
|
-
wreq::header::COOKIE,
|
|
184
|
-
wreq::header::HeaderValue::from_static("foo=bar"),
|
|
185
|
-
)
|
|
169
|
+
.get(format!("http://{}/sensitive", start_server.addr()))
|
|
170
|
+
.header(header::COOKIE, header::HeaderValue::from_static("foo=bar"))
|
|
186
171
|
.send()
|
|
187
172
|
.await
|
|
188
173
|
.unwrap();
|
|
174
|
+
|
|
175
|
+
assert_eq!(response.uri().path(), "/end");
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
#[tokio::test]
|
|
179
|
+
async fn test_redirect_referrer_policy() {
|
|
180
|
+
let server = server::http(move |req| async move {
|
|
181
|
+
match req.uri().path() {
|
|
182
|
+
"/direct-start" => http::Response::builder()
|
|
183
|
+
.status(302)
|
|
184
|
+
.header(header::LOCATION, "/direct-end")
|
|
185
|
+
.body(Body::default())
|
|
186
|
+
.unwrap(),
|
|
187
|
+
"/direct-end" => {
|
|
188
|
+
assert_eq!(req.headers().get(header::REFERER), None);
|
|
189
|
+
http::Response::default()
|
|
190
|
+
}
|
|
191
|
+
"/no-referrer-start" => http::Response::builder()
|
|
192
|
+
.status(302)
|
|
193
|
+
.header(header::LOCATION, "/no-referrer-end")
|
|
194
|
+
.header(header::REFERRER_POLICY, "no-referrer")
|
|
195
|
+
.body(Body::default())
|
|
196
|
+
.unwrap(),
|
|
197
|
+
"/no-referrer-end" => {
|
|
198
|
+
assert_eq!(req.headers().get(header::REFERER), None);
|
|
199
|
+
http::Response::default()
|
|
200
|
+
}
|
|
201
|
+
"/origin-start" => http::Response::builder()
|
|
202
|
+
.status(302)
|
|
203
|
+
.header(header::LOCATION, "/origin-end")
|
|
204
|
+
.header(
|
|
205
|
+
header::REFERRER_POLICY,
|
|
206
|
+
"unknown-policy, origin-when-cross-origin",
|
|
207
|
+
)
|
|
208
|
+
.body(Body::default())
|
|
209
|
+
.unwrap(),
|
|
210
|
+
"/origin-end" => {
|
|
211
|
+
assert_eq!(req.headers()[header::REFERER], "http://source.example/");
|
|
212
|
+
http::Response::default()
|
|
213
|
+
}
|
|
214
|
+
"/clear-start" => http::Response::builder()
|
|
215
|
+
.status(302)
|
|
216
|
+
.header(header::LOCATION, "/clear-middle")
|
|
217
|
+
.header(header::REFERRER_POLICY, "no-referrer")
|
|
218
|
+
.body(Body::default())
|
|
219
|
+
.unwrap(),
|
|
220
|
+
"/clear-middle" => {
|
|
221
|
+
assert_eq!(req.headers().get(header::REFERER), None);
|
|
222
|
+
http::Response::builder()
|
|
223
|
+
.status(302)
|
|
224
|
+
.header(header::LOCATION, "/clear-end")
|
|
225
|
+
.header(header::REFERRER_POLICY, "unsafe-url")
|
|
226
|
+
.body(Body::default())
|
|
227
|
+
.unwrap()
|
|
228
|
+
}
|
|
229
|
+
"/clear-end" => {
|
|
230
|
+
assert_eq!(req.headers().get(header::REFERER), None);
|
|
231
|
+
http::Response::default()
|
|
232
|
+
}
|
|
233
|
+
path => panic!("unexpected redirect path: {path}"),
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
let client = Client::builder()
|
|
238
|
+
.redirect(Policy::default())
|
|
239
|
+
.build()
|
|
240
|
+
.unwrap();
|
|
241
|
+
let base = format!("http://{}", server.addr());
|
|
242
|
+
|
|
243
|
+
let cases = [
|
|
244
|
+
("/direct-start", "/direct-end", None),
|
|
245
|
+
(
|
|
246
|
+
"/no-referrer-start",
|
|
247
|
+
"/no-referrer-end",
|
|
248
|
+
Some("https://source.example/private?q=1"),
|
|
249
|
+
),
|
|
250
|
+
(
|
|
251
|
+
"/origin-start",
|
|
252
|
+
"/origin-end",
|
|
253
|
+
Some("http://source.example/private?q=1"),
|
|
254
|
+
),
|
|
255
|
+
(
|
|
256
|
+
"/clear-start",
|
|
257
|
+
"/clear-end",
|
|
258
|
+
Some("http://source.example/private"),
|
|
259
|
+
),
|
|
260
|
+
];
|
|
261
|
+
|
|
262
|
+
for (start, end, referer) in cases {
|
|
263
|
+
let mut request = client.get(format!("{base}{start}"));
|
|
264
|
+
if let Some(referer) = referer {
|
|
265
|
+
request = request.header(header::REFERER, referer);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
let response = request.send().await.unwrap();
|
|
269
|
+
assert_eq!(response.uri().path(), end, "case: {start}");
|
|
270
|
+
}
|
|
189
271
|
}
|
|
190
272
|
|
|
191
273
|
#[tokio::test]
|
|
@@ -194,7 +276,7 @@ async fn test_redirect_policy_can_return_errors() {
|
|
|
194
276
|
assert_eq!(req.uri(), "/loop");
|
|
195
277
|
http::Response::builder()
|
|
196
278
|
.status(302)
|
|
197
|
-
.header(
|
|
279
|
+
.header(header::LOCATION, "/loop")
|
|
198
280
|
.body(Body::default())
|
|
199
281
|
.unwrap()
|
|
200
282
|
});
|
|
@@ -214,7 +296,7 @@ async fn test_redirect_policy_can_stop_redirects_without_an_error() {
|
|
|
214
296
|
assert_eq!(req.uri(), "/no-redirect");
|
|
215
297
|
http::Response::builder()
|
|
216
298
|
.status(302)
|
|
217
|
-
.header(
|
|
299
|
+
.header(header::LOCATION, "/dont")
|
|
218
300
|
.body(Body::default())
|
|
219
301
|
.unwrap()
|
|
220
302
|
});
|
|
@@ -235,30 +317,40 @@ async fn test_redirect_policy_can_stop_redirects_without_an_error() {
|
|
|
235
317
|
}
|
|
236
318
|
|
|
237
319
|
#[tokio::test]
|
|
238
|
-
async fn
|
|
320
|
+
async fn test_referer_is_preserved_if_disabled() {
|
|
239
321
|
let server = server::http(move |req| async move {
|
|
240
322
|
if req.uri() == "/no-refer" {
|
|
241
323
|
http::Response::builder()
|
|
242
324
|
.status(302)
|
|
243
|
-
.header(
|
|
325
|
+
.header(header::LOCATION, "/dst")
|
|
244
326
|
.body(Body::default())
|
|
245
327
|
.unwrap()
|
|
246
328
|
} else {
|
|
247
329
|
assert_eq!(req.uri(), "/dst");
|
|
248
|
-
assert_eq!(
|
|
330
|
+
assert_eq!(
|
|
331
|
+
req.headers()[header::REFERER],
|
|
332
|
+
"https://source.example/private?q=1"
|
|
333
|
+
);
|
|
249
334
|
|
|
250
335
|
http::Response::default()
|
|
251
336
|
}
|
|
252
337
|
});
|
|
253
338
|
|
|
254
|
-
Client::builder()
|
|
339
|
+
let response = Client::builder()
|
|
340
|
+
.redirect(Policy::default())
|
|
255
341
|
.referer(false)
|
|
256
342
|
.build()
|
|
257
343
|
.unwrap()
|
|
258
344
|
.get(format!("http://{}/no-refer", server.addr()))
|
|
345
|
+
.header(
|
|
346
|
+
header::REFERER,
|
|
347
|
+
header::HeaderValue::from_static("https://source.example/private?q=1"),
|
|
348
|
+
)
|
|
259
349
|
.send()
|
|
260
350
|
.await
|
|
261
351
|
.unwrap();
|
|
352
|
+
|
|
353
|
+
assert_eq!(response.uri().path(), "/dst");
|
|
262
354
|
}
|
|
263
355
|
|
|
264
356
|
#[tokio::test]
|
|
@@ -266,7 +358,7 @@ async fn test_invalid_location_stops_redirect_gh484() {
|
|
|
266
358
|
let server = server::http(move |_req| async move {
|
|
267
359
|
http::Response::builder()
|
|
268
360
|
.status(302)
|
|
269
|
-
.header(
|
|
361
|
+
.header(header::LOCATION, "http://www.yikes{KABOOM}")
|
|
270
362
|
.body(Body::default())
|
|
271
363
|
.unwrap()
|
|
272
364
|
});
|
|
@@ -284,7 +376,7 @@ async fn test_invalid_scheme_is_rejected() {
|
|
|
284
376
|
let server = server::http(move |_req| async move {
|
|
285
377
|
http::Response::builder()
|
|
286
378
|
.status(302)
|
|
287
|
-
.header(
|
|
379
|
+
.header(header::LOCATION, "htt://www.yikes.com/")
|
|
288
380
|
.body(Body::default())
|
|
289
381
|
.unwrap()
|
|
290
382
|
});
|
|
@@ -307,13 +399,13 @@ async fn test_redirect_302_with_set_cookies() {
|
|
|
307
399
|
if req.uri() == "/302" {
|
|
308
400
|
http::Response::builder()
|
|
309
401
|
.status(302)
|
|
310
|
-
.header(
|
|
311
|
-
.header(
|
|
402
|
+
.header(header::LOCATION, "/dst")
|
|
403
|
+
.header(header::SET_COOKIE, "key=value")
|
|
312
404
|
.body(Body::default())
|
|
313
405
|
.unwrap()
|
|
314
406
|
} else {
|
|
315
407
|
assert_eq!(req.uri(), "/dst");
|
|
316
|
-
assert_eq!(req.headers()[
|
|
408
|
+
assert_eq!(req.headers()[header::COOKIE], "key=value");
|
|
317
409
|
http::Response::default()
|
|
318
410
|
}
|
|
319
411
|
});
|
|
@@ -346,7 +438,7 @@ async fn test_redirect_limit_to_1() {
|
|
|
346
438
|
assert!(req.uri().path().ends_with(&format!("/redirect/{i}")));
|
|
347
439
|
http::Response::builder()
|
|
348
440
|
.status(302)
|
|
349
|
-
.header(
|
|
441
|
+
.header(header::LOCATION, format!("/redirect/{}", i + 1))
|
|
350
442
|
.body(Body::default())
|
|
351
443
|
.unwrap()
|
|
352
444
|
});
|
|
@@ -371,7 +463,7 @@ async fn test_scheme_only_check_after_policy_return_follow() {
|
|
|
371
463
|
let server = server::http(move |_| async move {
|
|
372
464
|
http::Response::builder()
|
|
373
465
|
.status(302)
|
|
374
|
-
.header(
|
|
466
|
+
.header(header::LOCATION, "htt://www.yikes.com/")
|
|
375
467
|
.body(Body::default())
|
|
376
468
|
.unwrap()
|
|
377
469
|
});
|
|
@@ -416,24 +508,24 @@ async fn test_redirect_301_302_303_empty_payload_headers() {
|
|
|
416
508
|
.unwrap();
|
|
417
509
|
|
|
418
510
|
assert_eq!(&*data, b"Hello");
|
|
419
|
-
if req.headers().get(
|
|
420
|
-
assert_eq!(req.headers()[
|
|
511
|
+
if req.headers().get(header::CONTENT_LENGTH).is_some() {
|
|
512
|
+
assert_eq!(req.headers()[header::CONTENT_LENGTH], "5");
|
|
421
513
|
}
|
|
422
514
|
assert_eq!(req.uri(), &*format!("/{code}"));
|
|
423
515
|
|
|
424
516
|
http::Response::builder()
|
|
425
|
-
.header(
|
|
426
|
-
.header(
|
|
517
|
+
.header(header::LOCATION, "/dst")
|
|
518
|
+
.header(header::SERVER, "test-dst")
|
|
427
519
|
.status(code)
|
|
428
520
|
.body(Body::default())
|
|
429
521
|
.unwrap()
|
|
430
522
|
} else {
|
|
431
523
|
assert_eq!(req.method(), "GET");
|
|
432
|
-
assert!(req.headers().get(
|
|
433
|
-
assert!(req.headers().get(
|
|
434
|
-
assert!(req.headers().get(
|
|
524
|
+
assert!(req.headers().get(header::CONTENT_TYPE).is_none());
|
|
525
|
+
assert!(req.headers().get(header::CONTENT_LENGTH).is_none());
|
|
526
|
+
assert!(req.headers().get(header::CONTENT_ENCODING).is_none());
|
|
435
527
|
http::Response::builder()
|
|
436
|
-
.header(
|
|
528
|
+
.header(header::SERVER, "test-dst")
|
|
437
529
|
.body(Body::default())
|
|
438
530
|
.unwrap()
|
|
439
531
|
}
|
|
@@ -444,18 +536,15 @@ async fn test_redirect_301_302_303_empty_payload_headers() {
|
|
|
444
536
|
let res = wreq::post(&url)
|
|
445
537
|
.redirect(Policy::default())
|
|
446
538
|
.body("Hello")
|
|
447
|
-
.header(
|
|
448
|
-
.header(
|
|
449
|
-
.header(
|
|
539
|
+
.header(header::CONTENT_TYPE, "text/plain")
|
|
540
|
+
.header(header::CONTENT_LENGTH, "5")
|
|
541
|
+
.header(header::CONTENT_ENCODING, "identity")
|
|
450
542
|
.send()
|
|
451
543
|
.await
|
|
452
544
|
.unwrap();
|
|
453
545
|
assert_eq!(res.uri(), dst.as_str());
|
|
454
546
|
assert_eq!(res.status(), 200);
|
|
455
|
-
assert_eq!(
|
|
456
|
-
res.headers().get(wreq::header::SERVER).unwrap(),
|
|
457
|
-
&"test-dst"
|
|
458
|
-
);
|
|
547
|
+
assert_eq!(res.headers().get(header::SERVER).unwrap(), &"test-dst");
|
|
459
548
|
}
|
|
460
549
|
}
|
|
461
550
|
|
|
@@ -465,20 +554,20 @@ async fn test_redirect_history() {
|
|
|
465
554
|
if req.uri() == "/first" {
|
|
466
555
|
http::Response::builder()
|
|
467
556
|
.status(302)
|
|
468
|
-
.header(
|
|
557
|
+
.header(header::LOCATION, "/second")
|
|
469
558
|
.body(Body::default())
|
|
470
559
|
.unwrap()
|
|
471
560
|
} else if req.uri() == "/second" {
|
|
472
561
|
http::Response::builder()
|
|
473
562
|
.status(302)
|
|
474
|
-
.header(
|
|
563
|
+
.header(header::LOCATION, "/dst")
|
|
475
564
|
.body(Body::default())
|
|
476
565
|
.unwrap()
|
|
477
566
|
} else {
|
|
478
567
|
assert_eq!(req.uri(), "/dst");
|
|
479
568
|
|
|
480
569
|
http::Response::builder()
|
|
481
|
-
.header(
|
|
570
|
+
.header(header::SERVER, "test-dst")
|
|
482
571
|
.body(Body::default())
|
|
483
572
|
.unwrap()
|
|
484
573
|
}
|
|
@@ -495,10 +584,7 @@ async fn test_redirect_history() {
|
|
|
495
584
|
let res = client.get(&url).send().await.unwrap();
|
|
496
585
|
assert_eq!(res.uri(), dst.as_str());
|
|
497
586
|
assert_eq!(res.status(), wreq::StatusCode::OK);
|
|
498
|
-
assert_eq!(
|
|
499
|
-
res.headers().get(wreq::header::SERVER).unwrap(),
|
|
500
|
-
&"test-dst"
|
|
501
|
-
);
|
|
587
|
+
assert_eq!(res.headers().get(header::SERVER).unwrap(), &"test-dst");
|
|
502
588
|
|
|
503
589
|
let mut history = res.extensions().get::<History>().unwrap().into_iter();
|
|
504
590
|
|
|
@@ -506,13 +592,13 @@ async fn test_redirect_history() {
|
|
|
506
592
|
assert_eq!(next1.status, 302);
|
|
507
593
|
assert_eq!(next1.previous.path(), "/first");
|
|
508
594
|
assert_eq!(next1.uri.path(), "/second");
|
|
509
|
-
assert_eq!(next1.headers[
|
|
595
|
+
assert_eq!(next1.headers[header::LOCATION], "/second");
|
|
510
596
|
|
|
511
597
|
let next2 = history.next().unwrap();
|
|
512
598
|
assert_eq!(next2.status, 302);
|
|
513
599
|
assert_eq!(next2.previous.path(), "/second");
|
|
514
600
|
assert_eq!(next2.uri.path(), "/dst");
|
|
515
|
-
assert_eq!(next2.headers[
|
|
601
|
+
assert_eq!(next2.headers[header::LOCATION], "/dst");
|
|
516
602
|
|
|
517
603
|
assert!(history.next().is_none());
|
|
518
604
|
}
|
|
@@ -524,12 +610,12 @@ async fn test_redirect_applies_set_cookie_from_redirect() {
|
|
|
524
610
|
match req.uri().path() {
|
|
525
611
|
"/start" => http::Response::builder()
|
|
526
612
|
.status(302)
|
|
527
|
-
.header(
|
|
528
|
-
.header(
|
|
613
|
+
.header(header::LOCATION, "/dst")
|
|
614
|
+
.header(header::SET_COOKIE, "session=abc; Path=/")
|
|
529
615
|
.body(Body::default())
|
|
530
616
|
.unwrap(),
|
|
531
617
|
"/dst" => {
|
|
532
|
-
assert_eq!(req.headers()[
|
|
618
|
+
assert_eq!(req.headers()[header::COOKIE], "session=abc");
|
|
533
619
|
http::Response::builder()
|
|
534
620
|
.status(200)
|
|
535
621
|
.body(Body::default())
|
|
@@ -562,13 +648,13 @@ async fn test_redirect_async_pending_follow() {
|
|
|
562
648
|
if req.uri() == "/async-redirect" {
|
|
563
649
|
http::Response::builder()
|
|
564
650
|
.status(302)
|
|
565
|
-
.header(
|
|
651
|
+
.header(header::LOCATION, "/dst")
|
|
566
652
|
.body(Body::default())
|
|
567
653
|
.unwrap()
|
|
568
654
|
} else {
|
|
569
655
|
assert_eq!(req.uri(), "/dst");
|
|
570
656
|
http::Response::builder()
|
|
571
|
-
.header(
|
|
657
|
+
.header(header::SERVER, "test-dst")
|
|
572
658
|
.body(Body::default())
|
|
573
659
|
.unwrap()
|
|
574
660
|
}
|
|
@@ -591,10 +677,7 @@ async fn test_redirect_async_pending_follow() {
|
|
|
591
677
|
let res = client.get(&url).send().await.unwrap();
|
|
592
678
|
assert_eq!(res.uri(), dst.as_str());
|
|
593
679
|
assert_eq!(res.status(), wreq::StatusCode::OK);
|
|
594
|
-
assert_eq!(
|
|
595
|
-
res.headers().get(wreq::header::SERVER).unwrap(),
|
|
596
|
-
&"test-dst"
|
|
597
|
-
);
|
|
680
|
+
assert_eq!(res.headers().get(header::SERVER).unwrap(), &"test-dst");
|
|
598
681
|
}
|
|
599
682
|
|
|
600
683
|
#[tokio::test]
|
|
@@ -603,7 +686,7 @@ async fn test_redirect_location_is_encoded() {
|
|
|
603
686
|
if req.uri() == "/start" {
|
|
604
687
|
http::Response::builder()
|
|
605
688
|
.status(302)
|
|
606
|
-
.header(
|
|
689
|
+
.header(header::LOCATION, "/dst path")
|
|
607
690
|
.body(wreq::Body::default())
|
|
608
691
|
.unwrap()
|
|
609
692
|
} else {
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
mod support;
|
|
2
|
-
use std::
|
|
2
|
+
use std::{
|
|
3
|
+
net::{Ipv4Addr, SocketAddr},
|
|
4
|
+
time::Duration,
|
|
5
|
+
};
|
|
3
6
|
|
|
4
7
|
use pretty_env_logger::env_logger;
|
|
5
|
-
use support::server;
|
|
8
|
+
use support::{layer::DelayLayer, server};
|
|
6
9
|
use wreq::Client;
|
|
7
10
|
|
|
8
11
|
#[tokio::test]
|
|
@@ -61,16 +64,19 @@ async fn request_timeout() {
|
|
|
61
64
|
async fn connect_timeout() {
|
|
62
65
|
let _ = env_logger::try_init();
|
|
63
66
|
|
|
67
|
+
let server = server::http(move |_req| async { http::Response::default() });
|
|
68
|
+
|
|
64
69
|
let client = Client::builder()
|
|
70
|
+
.connector_layer(DelayLayer::new(Duration::from_secs(60)))
|
|
65
71
|
.connect_timeout(Duration::from_millis(100))
|
|
66
72
|
.no_proxy()
|
|
67
73
|
.build()
|
|
68
74
|
.unwrap();
|
|
69
75
|
|
|
70
|
-
let url = "http://
|
|
76
|
+
let url = format!("http://{}", server.addr());
|
|
71
77
|
|
|
72
78
|
let err = client
|
|
73
|
-
.get(url)
|
|
79
|
+
.get(&url)
|
|
74
80
|
.timeout(Duration::from_millis(1000))
|
|
75
81
|
.send()
|
|
76
82
|
.await
|
|
@@ -84,13 +90,13 @@ async fn connect_many_timeout_succeeds() {
|
|
|
84
90
|
let _ = env_logger::try_init();
|
|
85
91
|
|
|
86
92
|
let server = server::http(move |_req| async { http::Response::default() });
|
|
93
|
+
let unavailable = std::net::TcpListener::bind((Ipv4Addr::LOCALHOST, 0)).unwrap();
|
|
94
|
+
let unavailable_addr = unavailable.local_addr().unwrap();
|
|
95
|
+
drop(unavailable);
|
|
87
96
|
let port = server.addr().port();
|
|
88
97
|
|
|
89
98
|
let client = Client::builder()
|
|
90
|
-
.resolve_to_addrs(
|
|
91
|
-
"many_addrs",
|
|
92
|
-
["127.0.0.1:81".parse().unwrap(), server.addr()],
|
|
93
|
-
)
|
|
99
|
+
.resolve_to_addrs("many_addrs", [unavailable_addr, server.addr()])
|
|
94
100
|
.connect_timeout(Duration::from_millis(100))
|
|
95
101
|
.no_proxy()
|
|
96
102
|
.build()
|
|
@@ -114,10 +120,11 @@ async fn connect_many_timeout() {
|
|
|
114
120
|
.resolve_to_addrs(
|
|
115
121
|
"many_addrs",
|
|
116
122
|
[
|
|
117
|
-
|
|
118
|
-
|
|
123
|
+
SocketAddr::from((Ipv4Addr::LOCALHOST, 81)),
|
|
124
|
+
SocketAddr::from((Ipv4Addr::LOCALHOST, 82)),
|
|
119
125
|
],
|
|
120
126
|
)
|
|
127
|
+
.connector_layer(DelayLayer::new(Duration::from_secs(60)))
|
|
121
128
|
.connect_timeout(Duration::from_millis(100))
|
|
122
129
|
.no_proxy()
|
|
123
130
|
.build()
|
|
@@ -162,7 +169,35 @@ async fn response_timeout() {
|
|
|
162
169
|
let res = client.get(&url).send().await.expect("Failed to get");
|
|
163
170
|
let err = res.text().await.unwrap_err();
|
|
164
171
|
|
|
165
|
-
assert!(err.is_timeout());
|
|
172
|
+
assert!(err.is_body() && err.is_timeout());
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
#[cfg(feature = "stream")]
|
|
176
|
+
#[tokio::test]
|
|
177
|
+
async fn total_timeout_includes_response_head_and_body() {
|
|
178
|
+
let _ = env_logger::try_init();
|
|
179
|
+
|
|
180
|
+
// Each delay is shorter than the timeout, but together they exceed it.
|
|
181
|
+
let server = server::http(move |_req| async {
|
|
182
|
+
tokio::time::sleep(Duration::from_millis(150)).await;
|
|
183
|
+
let body = wreq::Body::wrap_stream(futures_util::stream::once(async {
|
|
184
|
+
tokio::time::sleep(Duration::from_millis(150)).await;
|
|
185
|
+
Ok::<_, std::convert::Infallible>("Hello")
|
|
186
|
+
}));
|
|
187
|
+
http::Response::new(body)
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
let client = Client::builder()
|
|
191
|
+
.timeout(Duration::from_millis(220))
|
|
192
|
+
.no_proxy()
|
|
193
|
+
.build()
|
|
194
|
+
.unwrap();
|
|
195
|
+
|
|
196
|
+
let url = format!("http://{}/slow", server.addr());
|
|
197
|
+
let res = client.get(&url).send().await.expect("Failed to get");
|
|
198
|
+
let err = res.text().await.unwrap_err();
|
|
199
|
+
|
|
200
|
+
assert!(err.is_body() && err.is_timeout());
|
|
166
201
|
}
|
|
167
202
|
|
|
168
203
|
#[tokio::test]
|
|
@@ -218,7 +253,7 @@ async fn read_timeout_applies_to_body() {
|
|
|
218
253
|
let res = client.get(&url).send().await.expect("Failed to get");
|
|
219
254
|
let err = res.text().await.unwrap_err();
|
|
220
255
|
|
|
221
|
-
assert!(err.is_timeout());
|
|
256
|
+
assert!(err.is_body() && err.is_timeout());
|
|
222
257
|
}
|
|
223
258
|
|
|
224
259
|
#[cfg(feature = "stream")]
|
data/vendor/wreq/tests/zstd.rs
CHANGED