wreq-rb 0.3.0

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 (167) hide show
  1. checksums.yaml +7 -0
  2. data/Cargo.lock +2688 -0
  3. data/Cargo.toml +6 -0
  4. data/README.md +179 -0
  5. data/ext/wreq_rb/Cargo.toml +39 -0
  6. data/ext/wreq_rb/extconf.rb +22 -0
  7. data/ext/wreq_rb/src/client.rs +565 -0
  8. data/ext/wreq_rb/src/error.rs +25 -0
  9. data/ext/wreq_rb/src/lib.rs +20 -0
  10. data/ext/wreq_rb/src/response.rs +132 -0
  11. data/lib/wreq-rb/version.rb +5 -0
  12. data/lib/wreq-rb.rb +17 -0
  13. data/patches/0001-add-transfer-size-tracking.patch +292 -0
  14. data/vendor/wreq/Cargo.toml +306 -0
  15. data/vendor/wreq/LICENSE +202 -0
  16. data/vendor/wreq/README.md +122 -0
  17. data/vendor/wreq/examples/cert_store.rs +77 -0
  18. data/vendor/wreq/examples/connect_via_lower_priority_tokio_runtime.rs +258 -0
  19. data/vendor/wreq/examples/emulation.rs +118 -0
  20. data/vendor/wreq/examples/form.rs +14 -0
  21. data/vendor/wreq/examples/http1_websocket.rs +37 -0
  22. data/vendor/wreq/examples/http2_websocket.rs +45 -0
  23. data/vendor/wreq/examples/json_dynamic.rs +41 -0
  24. data/vendor/wreq/examples/json_typed.rs +47 -0
  25. data/vendor/wreq/examples/keylog.rs +16 -0
  26. data/vendor/wreq/examples/request_with_emulation.rs +115 -0
  27. data/vendor/wreq/examples/request_with_interface.rs +37 -0
  28. data/vendor/wreq/examples/request_with_local_address.rs +16 -0
  29. data/vendor/wreq/examples/request_with_proxy.rs +13 -0
  30. data/vendor/wreq/examples/request_with_redirect.rs +22 -0
  31. data/vendor/wreq/examples/request_with_version.rs +15 -0
  32. data/vendor/wreq/examples/tor_socks.rs +24 -0
  33. data/vendor/wreq/examples/unix_socket.rs +33 -0
  34. data/vendor/wreq/src/client/body.rs +304 -0
  35. data/vendor/wreq/src/client/conn/conn.rs +231 -0
  36. data/vendor/wreq/src/client/conn/connector.rs +549 -0
  37. data/vendor/wreq/src/client/conn/http.rs +1023 -0
  38. data/vendor/wreq/src/client/conn/proxy/socks.rs +233 -0
  39. data/vendor/wreq/src/client/conn/proxy/tunnel.rs +260 -0
  40. data/vendor/wreq/src/client/conn/proxy.rs +39 -0
  41. data/vendor/wreq/src/client/conn/tls_info.rs +98 -0
  42. data/vendor/wreq/src/client/conn/uds.rs +44 -0
  43. data/vendor/wreq/src/client/conn/verbose.rs +149 -0
  44. data/vendor/wreq/src/client/conn.rs +323 -0
  45. data/vendor/wreq/src/client/core/body/incoming.rs +485 -0
  46. data/vendor/wreq/src/client/core/body/length.rs +118 -0
  47. data/vendor/wreq/src/client/core/body.rs +34 -0
  48. data/vendor/wreq/src/client/core/common/buf.rs +149 -0
  49. data/vendor/wreq/src/client/core/common/rewind.rs +141 -0
  50. data/vendor/wreq/src/client/core/common/watch.rs +76 -0
  51. data/vendor/wreq/src/client/core/common.rs +3 -0
  52. data/vendor/wreq/src/client/core/conn/http1.rs +342 -0
  53. data/vendor/wreq/src/client/core/conn/http2.rs +307 -0
  54. data/vendor/wreq/src/client/core/conn.rs +11 -0
  55. data/vendor/wreq/src/client/core/dispatch.rs +299 -0
  56. data/vendor/wreq/src/client/core/error.rs +435 -0
  57. data/vendor/wreq/src/client/core/ext.rs +201 -0
  58. data/vendor/wreq/src/client/core/http1.rs +178 -0
  59. data/vendor/wreq/src/client/core/http2.rs +483 -0
  60. data/vendor/wreq/src/client/core/proto/h1/conn.rs +988 -0
  61. data/vendor/wreq/src/client/core/proto/h1/decode.rs +1170 -0
  62. data/vendor/wreq/src/client/core/proto/h1/dispatch.rs +684 -0
  63. data/vendor/wreq/src/client/core/proto/h1/encode.rs +580 -0
  64. data/vendor/wreq/src/client/core/proto/h1/io.rs +879 -0
  65. data/vendor/wreq/src/client/core/proto/h1/role.rs +694 -0
  66. data/vendor/wreq/src/client/core/proto/h1.rs +104 -0
  67. data/vendor/wreq/src/client/core/proto/h2/client.rs +650 -0
  68. data/vendor/wreq/src/client/core/proto/h2/ping.rs +539 -0
  69. data/vendor/wreq/src/client/core/proto/h2.rs +379 -0
  70. data/vendor/wreq/src/client/core/proto/headers.rs +138 -0
  71. data/vendor/wreq/src/client/core/proto.rs +58 -0
  72. data/vendor/wreq/src/client/core/rt/bounds.rs +57 -0
  73. data/vendor/wreq/src/client/core/rt/timer.rs +150 -0
  74. data/vendor/wreq/src/client/core/rt/tokio.rs +99 -0
  75. data/vendor/wreq/src/client/core/rt.rs +25 -0
  76. data/vendor/wreq/src/client/core/upgrade.rs +267 -0
  77. data/vendor/wreq/src/client/core.rs +16 -0
  78. data/vendor/wreq/src/client/emulation.rs +161 -0
  79. data/vendor/wreq/src/client/http/client/error.rs +142 -0
  80. data/vendor/wreq/src/client/http/client/exec.rs +29 -0
  81. data/vendor/wreq/src/client/http/client/extra.rs +77 -0
  82. data/vendor/wreq/src/client/http/client/lazy.rs +79 -0
  83. data/vendor/wreq/src/client/http/client/pool.rs +1105 -0
  84. data/vendor/wreq/src/client/http/client/util.rs +104 -0
  85. data/vendor/wreq/src/client/http/client.rs +1003 -0
  86. data/vendor/wreq/src/client/http/future.rs +99 -0
  87. data/vendor/wreq/src/client/http.rs +1629 -0
  88. data/vendor/wreq/src/client/layer/config/options.rs +156 -0
  89. data/vendor/wreq/src/client/layer/config.rs +116 -0
  90. data/vendor/wreq/src/client/layer/cookie.rs +161 -0
  91. data/vendor/wreq/src/client/layer/decoder.rs +139 -0
  92. data/vendor/wreq/src/client/layer/redirect/future.rs +270 -0
  93. data/vendor/wreq/src/client/layer/redirect/policy.rs +63 -0
  94. data/vendor/wreq/src/client/layer/redirect.rs +145 -0
  95. data/vendor/wreq/src/client/layer/retry/classify.rs +105 -0
  96. data/vendor/wreq/src/client/layer/retry/scope.rs +51 -0
  97. data/vendor/wreq/src/client/layer/retry.rs +151 -0
  98. data/vendor/wreq/src/client/layer/timeout/body.rs +233 -0
  99. data/vendor/wreq/src/client/layer/timeout/future.rs +90 -0
  100. data/vendor/wreq/src/client/layer/timeout.rs +177 -0
  101. data/vendor/wreq/src/client/layer.rs +15 -0
  102. data/vendor/wreq/src/client/multipart.rs +717 -0
  103. data/vendor/wreq/src/client/request.rs +818 -0
  104. data/vendor/wreq/src/client/response.rs +534 -0
  105. data/vendor/wreq/src/client/ws/json.rs +99 -0
  106. data/vendor/wreq/src/client/ws/message.rs +453 -0
  107. data/vendor/wreq/src/client/ws.rs +714 -0
  108. data/vendor/wreq/src/client.rs +27 -0
  109. data/vendor/wreq/src/config.rs +140 -0
  110. data/vendor/wreq/src/cookie.rs +579 -0
  111. data/vendor/wreq/src/dns/gai.rs +249 -0
  112. data/vendor/wreq/src/dns/hickory.rs +78 -0
  113. data/vendor/wreq/src/dns/resolve.rs +180 -0
  114. data/vendor/wreq/src/dns.rs +69 -0
  115. data/vendor/wreq/src/error.rs +502 -0
  116. data/vendor/wreq/src/ext.rs +398 -0
  117. data/vendor/wreq/src/hash.rs +143 -0
  118. data/vendor/wreq/src/header.rs +506 -0
  119. data/vendor/wreq/src/into_uri.rs +187 -0
  120. data/vendor/wreq/src/lib.rs +586 -0
  121. data/vendor/wreq/src/proxy/mac.rs +82 -0
  122. data/vendor/wreq/src/proxy/matcher.rs +806 -0
  123. data/vendor/wreq/src/proxy/uds.rs +66 -0
  124. data/vendor/wreq/src/proxy/win.rs +31 -0
  125. data/vendor/wreq/src/proxy.rs +569 -0
  126. data/vendor/wreq/src/redirect.rs +575 -0
  127. data/vendor/wreq/src/retry.rs +198 -0
  128. data/vendor/wreq/src/sync.rs +129 -0
  129. data/vendor/wreq/src/tls/conn/cache.rs +123 -0
  130. data/vendor/wreq/src/tls/conn/cert_compression.rs +125 -0
  131. data/vendor/wreq/src/tls/conn/ext.rs +82 -0
  132. data/vendor/wreq/src/tls/conn/macros.rs +34 -0
  133. data/vendor/wreq/src/tls/conn/service.rs +138 -0
  134. data/vendor/wreq/src/tls/conn.rs +681 -0
  135. data/vendor/wreq/src/tls/keylog/handle.rs +64 -0
  136. data/vendor/wreq/src/tls/keylog.rs +99 -0
  137. data/vendor/wreq/src/tls/options.rs +464 -0
  138. data/vendor/wreq/src/tls/x509/identity.rs +122 -0
  139. data/vendor/wreq/src/tls/x509/parser.rs +71 -0
  140. data/vendor/wreq/src/tls/x509/store.rs +228 -0
  141. data/vendor/wreq/src/tls/x509.rs +68 -0
  142. data/vendor/wreq/src/tls.rs +154 -0
  143. data/vendor/wreq/src/trace.rs +55 -0
  144. data/vendor/wreq/src/util.rs +122 -0
  145. data/vendor/wreq/tests/badssl.rs +228 -0
  146. data/vendor/wreq/tests/brotli.rs +350 -0
  147. data/vendor/wreq/tests/client.rs +1098 -0
  148. data/vendor/wreq/tests/connector_layers.rs +227 -0
  149. data/vendor/wreq/tests/cookie.rs +306 -0
  150. data/vendor/wreq/tests/deflate.rs +347 -0
  151. data/vendor/wreq/tests/emulation.rs +260 -0
  152. data/vendor/wreq/tests/gzip.rs +347 -0
  153. data/vendor/wreq/tests/layers.rs +261 -0
  154. data/vendor/wreq/tests/multipart.rs +165 -0
  155. data/vendor/wreq/tests/proxy.rs +438 -0
  156. data/vendor/wreq/tests/redirect.rs +629 -0
  157. data/vendor/wreq/tests/retry.rs +135 -0
  158. data/vendor/wreq/tests/support/delay_server.rs +117 -0
  159. data/vendor/wreq/tests/support/error.rs +16 -0
  160. data/vendor/wreq/tests/support/layer.rs +183 -0
  161. data/vendor/wreq/tests/support/mod.rs +9 -0
  162. data/vendor/wreq/tests/support/server.rs +232 -0
  163. data/vendor/wreq/tests/timeouts.rs +281 -0
  164. data/vendor/wreq/tests/unix_socket.rs +135 -0
  165. data/vendor/wreq/tests/upgrade.rs +98 -0
  166. data/vendor/wreq/tests/zstd.rs +559 -0
  167. metadata +225 -0
@@ -0,0 +1,281 @@
1
+ mod support;
2
+ use std::time::Duration;
3
+
4
+ use pretty_env_logger::env_logger;
5
+ use support::server;
6
+ use wreq::Client;
7
+
8
+ #[tokio::test]
9
+ async fn client_timeout() {
10
+ let _ = env_logger::try_init();
11
+
12
+ let server = server::http(move |_req| {
13
+ async {
14
+ // delay returning the response
15
+ tokio::time::sleep(Duration::from_millis(300)).await;
16
+ http::Response::default()
17
+ }
18
+ });
19
+
20
+ let client = Client::builder()
21
+ .timeout(Duration::from_millis(100))
22
+ .no_proxy()
23
+ .build()
24
+ .unwrap();
25
+
26
+ let url = format!("http://{}/slow", server.addr());
27
+ let err = client.get(&url).send().await.unwrap_err();
28
+
29
+ assert!(err.is_timeout());
30
+ assert_eq!(err.uri().map(|u| u.to_string()), Some(url));
31
+ }
32
+
33
+ #[tokio::test]
34
+ async fn request_timeout() {
35
+ let _ = env_logger::try_init();
36
+
37
+ let server = server::http(move |_req| {
38
+ async {
39
+ // delay returning the response
40
+ tokio::time::sleep(Duration::from_millis(300)).await;
41
+ http::Response::default()
42
+ }
43
+ });
44
+
45
+ let client = Client::builder().no_proxy().build().unwrap();
46
+
47
+ let url = format!("http://{}/slow", server.addr());
48
+
49
+ let err = client
50
+ .get(&url)
51
+ .timeout(Duration::from_millis(100))
52
+ .send()
53
+ .await
54
+ .unwrap_err();
55
+
56
+ assert!(err.is_timeout() && !err.is_connect());
57
+ assert_eq!(err.uri().map(|u| u.to_string()), Some(url));
58
+ }
59
+
60
+ #[tokio::test]
61
+ async fn connect_timeout() {
62
+ let _ = env_logger::try_init();
63
+
64
+ let client = Client::builder()
65
+ .connect_timeout(Duration::from_millis(100))
66
+ .no_proxy()
67
+ .build()
68
+ .unwrap();
69
+
70
+ let url = "http://192.0.2.1:81/slow";
71
+
72
+ let err = client
73
+ .get(url)
74
+ .timeout(Duration::from_millis(1000))
75
+ .send()
76
+ .await
77
+ .unwrap_err();
78
+
79
+ assert!(err.is_timeout());
80
+ }
81
+
82
+ #[tokio::test]
83
+ async fn connect_many_timeout_succeeds() {
84
+ let _ = env_logger::try_init();
85
+
86
+ let server = server::http(move |_req| async { http::Response::default() });
87
+ let port = server.addr().port();
88
+
89
+ let client = Client::builder()
90
+ .resolve_to_addrs(
91
+ "many_addrs",
92
+ ["127.0.0.1:81".parse().unwrap(), server.addr()],
93
+ )
94
+ .connect_timeout(Duration::from_millis(100))
95
+ .no_proxy()
96
+ .build()
97
+ .unwrap();
98
+
99
+ let url = format!("http://many_addrs:{port}/eventual");
100
+
101
+ let _ = client
102
+ .get(url)
103
+ .timeout(Duration::from_millis(1000))
104
+ .send()
105
+ .await
106
+ .unwrap();
107
+ }
108
+
109
+ #[tokio::test]
110
+ async fn connect_many_timeout() {
111
+ let _ = env_logger::try_init();
112
+
113
+ let client = Client::builder()
114
+ .resolve_to_addrs(
115
+ "many_addrs",
116
+ [
117
+ "192.0.2.1:81".parse().unwrap(),
118
+ "192.0.2.2:81".parse().unwrap(),
119
+ ],
120
+ )
121
+ .connect_timeout(Duration::from_millis(100))
122
+ .no_proxy()
123
+ .build()
124
+ .unwrap();
125
+
126
+ let url = "http://many_addrs:81/slow".to_string();
127
+
128
+ let err = client
129
+ .get(url)
130
+ .timeout(Duration::from_millis(1000))
131
+ .send()
132
+ .await
133
+ .unwrap_err();
134
+
135
+ assert!(err.is_connect() && err.is_timeout());
136
+ }
137
+
138
+ #[cfg(feature = "stream")]
139
+ #[tokio::test]
140
+ async fn response_timeout() {
141
+ let _ = env_logger::try_init();
142
+
143
+ let server = server::http(move |_req| {
144
+ async {
145
+ // immediate response, but delayed body
146
+ let body = wreq::Body::wrap_stream(futures_util::stream::once(async {
147
+ tokio::time::sleep(Duration::from_secs(1)).await;
148
+ Ok::<_, std::convert::Infallible>("Hello")
149
+ }));
150
+
151
+ http::Response::new(body)
152
+ }
153
+ });
154
+
155
+ let client = Client::builder()
156
+ .timeout(Duration::from_millis(500))
157
+ .no_proxy()
158
+ .build()
159
+ .unwrap();
160
+
161
+ let url = format!("http://{}/slow", server.addr());
162
+ let res = client.get(&url).send().await.expect("Failed to get");
163
+ let err = res.text().await.unwrap_err();
164
+
165
+ assert!(err.is_timeout());
166
+ }
167
+
168
+ #[tokio::test]
169
+ async fn read_timeout_applies_to_headers() {
170
+ let _ = env_logger::try_init();
171
+
172
+ let server = server::http(move |_req| {
173
+ async {
174
+ // delay returning the response
175
+ tokio::time::sleep(Duration::from_millis(300)).await;
176
+ http::Response::default()
177
+ }
178
+ });
179
+
180
+ let client = Client::builder()
181
+ .read_timeout(Duration::from_millis(100))
182
+ .no_proxy()
183
+ .build()
184
+ .unwrap();
185
+
186
+ let url = format!("http://{}/slow", server.addr());
187
+
188
+ let err = client.get(&url).send().await.unwrap_err();
189
+
190
+ assert!(err.is_timeout());
191
+ assert_eq!(err.uri().map(|u| u.to_string()), Some(url));
192
+ }
193
+
194
+ #[cfg(feature = "stream")]
195
+ #[tokio::test]
196
+ async fn read_timeout_applies_to_body() {
197
+ let _ = env_logger::try_init();
198
+
199
+ let server = server::http(move |_req| {
200
+ async {
201
+ // immediate response, but delayed body
202
+ let body = wreq::Body::wrap_stream(futures_util::stream::once(async {
203
+ tokio::time::sleep(Duration::from_millis(300)).await;
204
+ Ok::<_, std::convert::Infallible>("Hello")
205
+ }));
206
+
207
+ http::Response::new(body)
208
+ }
209
+ });
210
+
211
+ let client = Client::builder()
212
+ .read_timeout(Duration::from_millis(100))
213
+ .no_proxy()
214
+ .build()
215
+ .unwrap();
216
+
217
+ let url = format!("http://{}/slow", server.addr());
218
+ let res = client.get(&url).send().await.expect("Failed to get");
219
+ let err = res.text().await.unwrap_err();
220
+
221
+ assert!(err.is_timeout());
222
+ }
223
+
224
+ #[cfg(feature = "stream")]
225
+ #[tokio::test]
226
+ async fn read_timeout_allows_slow_response_body() {
227
+ let _ = env_logger::try_init();
228
+
229
+ let server = server::http(move |_req| {
230
+ async {
231
+ // immediate response, but body that has slow chunks
232
+ let slow = futures_util::stream::unfold(0, |state| async move {
233
+ if state < 3 {
234
+ tokio::time::sleep(Duration::from_millis(100)).await;
235
+ Some((
236
+ Ok::<_, std::convert::Infallible>(state.to_string()),
237
+ state + 1,
238
+ ))
239
+ } else {
240
+ None
241
+ }
242
+ });
243
+ let body = wreq::Body::wrap_stream(slow);
244
+
245
+ http::Response::new(body)
246
+ }
247
+ });
248
+
249
+ let client = Client::builder()
250
+ .read_timeout(Duration::from_millis(200))
251
+ //.timeout(Duration::from_millis(200))
252
+ .no_proxy()
253
+ .build()
254
+ .unwrap();
255
+
256
+ let url = format!("http://{}/slow", server.addr());
257
+ let res = client.get(&url).send().await.expect("Failed to get");
258
+ let body = res.text().await.expect("body text");
259
+
260
+ assert_eq!(body, "012");
261
+ }
262
+
263
+ #[tokio::test]
264
+ async fn response_body_timeout_forwards_size_hint() {
265
+ let _ = env_logger::try_init();
266
+
267
+ let server = server::http(move |_req| async { http::Response::new(b"hello".to_vec().into()) });
268
+
269
+ let client = Client::builder().no_proxy().build().unwrap();
270
+
271
+ let url = format!("http://{}/slow", server.addr());
272
+
273
+ let res = client
274
+ .get(&url)
275
+ .timeout(Duration::from_secs(1))
276
+ .send()
277
+ .await
278
+ .expect("response");
279
+
280
+ assert_eq!(res.content_length(), Some(5));
281
+ }
@@ -0,0 +1,135 @@
1
+ #![cfg(unix)]
2
+
3
+ use std::{hash::BuildHasher, time::Duration};
4
+
5
+ use http::Method;
6
+ use http_body_util::Full;
7
+ use hyper::{Request, Response, body::Incoming, service::service_fn};
8
+ use hyper_util::{
9
+ rt::{TokioExecutor, TokioIo},
10
+ server::conn::auto::Builder,
11
+ };
12
+ use tokio::{net::UnixListener, task};
13
+ use wreq::{Client, Proxy};
14
+
15
+ fn random_sock_path() -> std::path::PathBuf {
16
+ let mut buf = std::env::temp_dir();
17
+ // libstd uses system random to create each one
18
+ let rng = std::collections::hash_map::RandomState::new();
19
+ let n = rng.hash_one("uds-sock");
20
+ buf.push(format!("test-uds-sock-{}", n));
21
+ buf
22
+ }
23
+
24
+ #[tokio::test]
25
+ async fn test_unix_socket() {
26
+ let sock_path = random_sock_path();
27
+
28
+ let listener = UnixListener::bind(&sock_path).unwrap();
29
+ let server = async move {
30
+ loop {
31
+ let (stream, _) = listener.accept().await.unwrap();
32
+ let io = TokioIo::new(stream);
33
+ let service = service_fn(|_req: Request<Incoming>| async {
34
+ Ok::<_, hyper::Error>(Response::new(Full::new(&b"hello unix"[..])))
35
+ });
36
+ task::spawn(async move {
37
+ if let Err(e) = hyper::server::conn::http1::Builder::new()
38
+ .serve_connection(io, service)
39
+ .await
40
+ {
41
+ eprintln!("server error: {:?}", e);
42
+ }
43
+ });
44
+ }
45
+ };
46
+ tokio::spawn(server);
47
+
48
+ let client = Client::builder()
49
+ .proxy(Proxy::unix(sock_path).unwrap())
50
+ .timeout(Duration::from_secs(10))
51
+ .build()
52
+ .unwrap();
53
+
54
+ let resp = client.get("http://localhost/").send().await.unwrap();
55
+ let body = resp.text().await.unwrap();
56
+ assert_eq!(body, "hello unix");
57
+ }
58
+
59
+ #[tokio::test]
60
+ async fn test_proxy_unix_socket() {
61
+ let sock_path = random_sock_path();
62
+
63
+ let listener = UnixListener::bind(&sock_path).unwrap();
64
+ let server = async move {
65
+ loop {
66
+ let (stream, _) = listener.accept().await.unwrap();
67
+ let io = TokioIo::new(stream);
68
+ let service = service_fn(|req: Request<Incoming>| {
69
+ async move {
70
+ if Method::CONNECT == req.method() {
71
+ // Received an HTTP request like:
72
+ // ```
73
+ // CONNECT www.domain.com:443 HTTP/1.1
74
+ // Host: www.domain.com:443
75
+ // Proxy-Connection: Keep-Alive
76
+ // ```
77
+ //
78
+ // When HTTP method is CONNECT we should return an empty body,
79
+ // then we can eventually upgrade the connection and talk a new protocol.
80
+ //
81
+ // Note: only after client received an empty body with STATUS_OK can the
82
+ // connection be upgraded, so we can't return a response inside
83
+ // `on_upgrade` future.
84
+ let authority = req.uri().authority().cloned().unwrap();
85
+ tokio::task::spawn({
86
+ let req = req;
87
+ async move {
88
+ match hyper::upgrade::on(req).await {
89
+ Ok(upgraded) => {
90
+ tracing::info!("upgraded connection to: {}", authority);
91
+ if let Ok(mut io) =
92
+ tokio::net::TcpStream::connect(authority.to_string())
93
+ .await
94
+ {
95
+ let _ = tokio::io::copy_bidirectional(
96
+ &mut TokioIo::new(upgraded),
97
+ &mut io,
98
+ )
99
+ .await;
100
+ }
101
+ }
102
+ Err(e) => tracing::warn!("upgrade error: {}", e),
103
+ }
104
+ }
105
+ });
106
+
107
+ Ok::<_, hyper::Error>(Response::new(Full::new(&b""[..])))
108
+ } else {
109
+ Ok::<_, hyper::Error>(Response::new(Full::new(
110
+ &b"unsupported request method"[..],
111
+ )))
112
+ }
113
+ }
114
+ });
115
+ task::spawn(async move {
116
+ if let Err(e) = Builder::new(TokioExecutor::new())
117
+ .serve_connection_with_upgrades(io, service)
118
+ .await
119
+ {
120
+ eprintln!("server error: {:?}", e);
121
+ }
122
+ });
123
+ }
124
+ };
125
+ tokio::spawn(server);
126
+
127
+ let client = Client::builder()
128
+ .proxy(Proxy::unix(sock_path).unwrap())
129
+ .timeout(Duration::from_secs(10))
130
+ .build()
131
+ .unwrap();
132
+
133
+ let resp = client.get("https://www.google.com").send().await.unwrap();
134
+ assert!(resp.status().is_success(), "Expected successful response");
135
+ }
@@ -0,0 +1,98 @@
1
+ mod support;
2
+ use http::Method;
3
+ use support::server;
4
+ use tokio::io::{AsyncReadExt, AsyncWriteExt};
5
+ use wreq::Client;
6
+
7
+ #[tokio::test]
8
+ async fn http_upgrade() {
9
+ let server = server::http(move |req| {
10
+ assert_eq!(req.method(), "GET");
11
+ assert_eq!(req.headers()["connection"], "upgrade");
12
+ assert_eq!(req.headers()["upgrade"], "foobar");
13
+
14
+ tokio::spawn(async move {
15
+ let mut upgraded = hyper_util::rt::TokioIo::new(hyper::upgrade::on(req).await.unwrap());
16
+
17
+ let mut buf = vec![0; 7];
18
+ upgraded.read_exact(&mut buf).await.unwrap();
19
+ assert_eq!(buf, b"foo=bar");
20
+
21
+ upgraded.write_all(b"bar=foo").await.unwrap();
22
+ });
23
+
24
+ async {
25
+ http::Response::builder()
26
+ .status(http::StatusCode::SWITCHING_PROTOCOLS)
27
+ .header(http::header::CONNECTION, "upgrade")
28
+ .header(http::header::UPGRADE, "foobar")
29
+ .body(wreq::Body::default())
30
+ .unwrap()
31
+ }
32
+ });
33
+
34
+ let res = Client::builder()
35
+ .build()
36
+ .unwrap()
37
+ .get(format!("http://{}", server.addr()))
38
+ .header(http::header::CONNECTION, "upgrade")
39
+ .header(http::header::UPGRADE, "foobar")
40
+ .send()
41
+ .await
42
+ .unwrap();
43
+
44
+ assert_eq!(res.status(), http::StatusCode::SWITCHING_PROTOCOLS);
45
+ let mut upgraded = res.upgrade().await.unwrap();
46
+
47
+ upgraded.write_all(b"foo=bar").await.unwrap();
48
+
49
+ let mut buf = vec![];
50
+ upgraded.read_to_end(&mut buf).await.unwrap();
51
+ assert_eq!(buf, b"bar=foo");
52
+ }
53
+
54
+ #[tokio::test]
55
+ async fn http2_upgrade() {
56
+ let server = server::http_with_config(
57
+ move |req| {
58
+ assert_eq!(req.method(), http::Method::CONNECT);
59
+ assert_eq!(req.version(), http::Version::HTTP_2);
60
+
61
+ tokio::spawn(async move {
62
+ let mut upgraded =
63
+ hyper_util::rt::TokioIo::new(hyper::upgrade::on(req).await.unwrap());
64
+
65
+ let mut buf = vec![0; 7];
66
+ upgraded.read_exact(&mut buf).await.unwrap();
67
+ assert_eq!(buf, b"foo=bar");
68
+
69
+ upgraded.write_all(b"bar=foo").await.unwrap();
70
+ });
71
+
72
+ async { Ok::<_, std::convert::Infallible>(http::Response::default()) }
73
+ },
74
+ |builder| {
75
+ let mut http2 = builder.http2();
76
+ http2.enable_connect_protocol();
77
+ },
78
+ );
79
+
80
+ let res = Client::builder()
81
+ .http2_only()
82
+ .build()
83
+ .unwrap()
84
+ .request(Method::CONNECT, format!("http://{}", server.addr()))
85
+ .send()
86
+ .await
87
+ .unwrap();
88
+
89
+ assert_eq!(res.status(), http::StatusCode::OK);
90
+ assert_eq!(res.version(), http::Version::HTTP_2);
91
+ let mut upgraded = res.upgrade().await.unwrap();
92
+
93
+ upgraded.write_all(b"foo=bar").await.unwrap();
94
+
95
+ let mut buf = vec![];
96
+ upgraded.read_to_end(&mut buf).await.unwrap();
97
+ assert_eq!(buf, b"bar=foo");
98
+ }