@@ -2,6 +2,13 @@ pub extern crate futures;
2
2
pub extern crate hyper;
3
3
pub extern crate tokio;
4
4
5
+ use std:: sync:: { Arc , Mutex , atomic:: { AtomicUsize , Ordering } } ;
6
+ use std:: time:: Duration ;
7
+
8
+ use hyper:: { Body , Client , Request , Response , Server , Version } ;
9
+ use hyper:: client:: HttpConnector ;
10
+ use hyper:: service:: service_fn;
11
+
5
12
pub use std:: net:: SocketAddr ;
6
13
pub use self :: futures:: { future, Future , Stream } ;
7
14
pub use self :: futures:: sync:: oneshot;
@@ -44,15 +51,25 @@ macro_rules! t {
44
51
) ) ;
45
52
}
46
53
54
+ __run_test( __TestConfig {
55
+ client_version: 2 ,
56
+ client_msgs: c. clone( ) ,
57
+ server_version: 2 ,
58
+ server_msgs: s. clone( ) ,
59
+ parallel: true ,
60
+ connections: 1 ,
61
+ proxy: false ,
62
+ } ) ;
63
+
47
64
__run_test( __TestConfig {
48
65
client_version: 2 ,
49
66
client_msgs: c,
50
67
server_version: 2 ,
51
68
server_msgs: s,
52
69
parallel: true ,
53
70
connections: 1 ,
71
+ proxy: true ,
54
72
} ) ;
55
-
56
73
}
57
74
) ;
58
75
(
@@ -104,6 +121,27 @@ macro_rules! t {
104
121
server_msgs: s. clone( ) ,
105
122
parallel: false ,
106
123
connections: 1 ,
124
+ proxy: false ,
125
+ } ) ;
126
+
127
+ __run_test( __TestConfig {
128
+ client_version: 2 ,
129
+ client_msgs: c. clone( ) ,
130
+ server_version: 2 ,
131
+ server_msgs: s. clone( ) ,
132
+ parallel: false ,
133
+ connections: 1 ,
134
+ proxy: false ,
135
+ } ) ;
136
+
137
+ __run_test( __TestConfig {
138
+ client_version: 1 ,
139
+ client_msgs: c. clone( ) ,
140
+ server_version: 1 ,
141
+ server_msgs: s. clone( ) ,
142
+ parallel: false ,
143
+ connections: 1 ,
144
+ proxy: true ,
107
145
} ) ;
108
146
109
147
__run_test( __TestConfig {
@@ -113,6 +151,7 @@ macro_rules! t {
113
151
server_msgs: s,
114
152
parallel: false ,
115
153
connections: 1 ,
154
+ proxy: true ,
116
155
} ) ;
117
156
}
118
157
) ;
@@ -185,14 +224,11 @@ pub struct __TestConfig {
185
224
186
225
pub parallel : bool ,
187
226
pub connections : usize ,
227
+ pub proxy : bool ,
188
228
}
189
229
190
230
pub fn __run_test ( cfg : __TestConfig ) {
191
231
extern crate pretty_env_logger;
192
- use hyper:: { Body , Client , Request , Response , Version } ;
193
- use hyper:: client:: HttpConnector ;
194
- use std:: sync:: { Arc , Mutex } ;
195
- use std:: time:: Duration ;
196
232
let _ = pretty_env_logger:: try_init ( ) ;
197
233
let mut rt = Runtime :: new ( ) . expect ( "new rt" ) ;
198
234
@@ -254,31 +290,39 @@ pub fn __run_test(cfg: __TestConfig) {
254
290
)
255
291
. expect ( "serve_addr" ) ;
256
292
257
- let addr = serve. incoming_ref ( ) . local_addr ( ) ;
258
- let ( shutdown_tx, shutdown_rx) = oneshot:: channel ( ) ;
259
- let ( success_tx, success_rx) = oneshot:: channel ( ) ;
293
+ let mut addr = serve. incoming_ref ( ) . local_addr ( ) ;
260
294
let expected_connections = cfg. connections ;
261
295
let server = serve
262
296
. fold ( 0 , move |cnt, connecting| {
297
+ let cnt = cnt + 1 ;
298
+ assert ! (
299
+ cnt <= expected_connections,
300
+ "server expected {} connections, received {}" ,
301
+ expected_connections,
302
+ cnt
303
+ ) ;
263
304
let fut = connecting
264
305
. map_err ( |never| -> hyper:: Error { match never { } } )
265
306
. flatten ( )
266
307
. map_err ( |e| panic ! ( "server connection error: {}" , e) ) ;
267
308
:: tokio:: spawn ( fut) ;
268
- Ok :: < _ , hyper:: Error > ( cnt + 1 )
269
- } )
270
- . map ( move |cnt| {
271
- assert_eq ! ( cnt, expected_connections) ;
272
- } )
273
- . map_err ( |e| panic ! ( "serve error: {}" , e) )
274
- . select2 ( shutdown_rx)
275
- . map ( move |_| {
276
- let _ = success_tx. send ( ( ) ) ;
309
+ Ok :: < _ , hyper:: Error > ( cnt)
277
310
} )
278
- . map_err ( |_| panic ! ( "shutdown not ok" ) ) ;
311
+ . map ( |_| ( ) )
312
+ . map_err ( |e| panic ! ( "serve error: {}" , e) ) ;
279
313
280
314
rt. spawn ( server) ;
281
315
316
+ if cfg. proxy {
317
+ let ( proxy_addr, proxy) = naive_proxy ( ProxyConfig {
318
+ connections : cfg. connections ,
319
+ dst : addr,
320
+ version : cfg. server_version ,
321
+ } ) ;
322
+ rt. spawn ( proxy) ;
323
+ addr = proxy_addr;
324
+ }
325
+
282
326
283
327
let make_request = Arc :: new ( move |client : & Client < HttpConnector > , creq : __CReq , cres : __CRes | {
284
328
let uri = format ! ( "http://{}{}" , addr, creq. uri) ;
@@ -335,12 +379,41 @@ pub fn __run_test(cfg: __TestConfig) {
335
379
Box :: new ( client_futures. map ( |_| ( ) ) )
336
380
} ;
337
381
338
- let client_futures = client_futures. map ( move |_| {
339
- let _ = shutdown_tx. send ( ( ) ) ;
340
- } ) ;
341
- rt. spawn ( client_futures) ;
342
- rt. block_on ( success_rx
343
- . map_err ( |_| "something panicked" ) )
382
+ let client_futures = client_futures. map ( |_| ( ) ) ;
383
+ rt. block_on ( client_futures)
344
384
. expect ( "shutdown succeeded" ) ;
345
385
}
346
386
387
+ struct ProxyConfig {
388
+ connections : usize ,
389
+ dst : SocketAddr ,
390
+ version : usize ,
391
+ }
392
+
393
+ fn naive_proxy ( cfg : ProxyConfig ) -> ( SocketAddr , impl Future < Item = ( ) , Error = ( ) > ) {
394
+ let client = Client :: builder ( )
395
+ . keep_alive_timeout ( Duration :: from_secs ( 10 ) )
396
+ . http2_only ( cfg. version == 2 )
397
+ . build_http :: < Body > ( ) ;
398
+
399
+ let dst_addr = cfg. dst ;
400
+ let max_connections = cfg. connections ;
401
+ let counter = AtomicUsize :: new ( 0 ) ;
402
+
403
+ let srv = Server :: bind ( & ( [ 127 , 0 , 0 , 1 ] , 0 ) . into ( ) )
404
+ . serve ( move || {
405
+ let prev = counter. fetch_add ( 1 , Ordering :: Relaxed ) ;
406
+ assert ! ( max_connections >= prev + 1 , "proxy max connections" ) ;
407
+ let client = client. clone ( ) ;
408
+ service_fn ( move |mut req| {
409
+ let uri = format ! ( "http://{}{}" , dst_addr, req. uri( ) . path( ) )
410
+ . parse ( )
411
+ . expect ( "proxy new uri parse" ) ;
412
+ * req. uri_mut ( ) = uri;
413
+ client. request ( req)
414
+ } )
415
+
416
+ } ) ;
417
+ let proxy_addr = srv. local_addr ( ) ;
418
+ ( proxy_addr, srv. map_err ( |err| panic ! ( "proxy error: {}" , err) ) )
419
+ }
0 commit comments