1
+ //! Contains the `Connect2` trait, and supporting types.
1
2
use std:: error:: Error as StdError ;
2
3
use std:: fmt;
3
4
use std:: io;
4
5
use std:: mem;
5
6
use std:: sync:: Arc ;
6
- //use std::net::SocketAddr;
7
7
8
8
use futures:: { Future , Poll , Async } ;
9
9
use futures:: future:: { Executor , ExecuteError } ;
@@ -16,31 +16,74 @@ use tokio_service::Service;
16
16
use Uri ;
17
17
18
18
use super :: dns;
19
+ use self :: http_connector:: HttpConnectorBlockingTask ;
20
+
21
+ /// Connect to a destination, returning an IO transport.
22
+ pub trait Connect2 {
23
+ /// The connected IO Stream.
24
+ type Transport : AsyncRead + AsyncWrite ;
25
+ /// An error occured when trying to connect.
26
+ type Error ;
27
+ /// A Future that will resolve to the connected Transport.
28
+ type Future : Future < Item =Connected < Self :: Transport > , Error =Self :: Error > ;
29
+ /// Connect to a destination.
30
+ fn connect ( & self , dst : Destination ) -> Self :: Future ;
31
+ }
19
32
20
- /// A connector creates an Io to a remote address..
21
- ///
22
- /// This trait is not implemented directly, and only exists to make
23
- /// the intent clearer. A connector should implement `Service` with
24
- /// `Request=Uri` and `Response: Io` instead.
25
- pub trait Connect : Service < Request =Uri , Error =io:: Error > + ' static {
26
- /// The connected Io Stream.
27
- type Output : AsyncRead + AsyncWrite + ' static ;
28
- /// A Future that will resolve to the connected Stream.
29
- type Future : Future < Item =Self :: Output , Error =io:: Error > + ' static ;
30
- /// Connect to a remote address.
31
- fn connect ( & self , Uri ) -> <Self as Connect >:: Future ;
33
+ /// A set of properties to describe where and how to try to connect.
34
+ #[ derive( Debug ) ]
35
+ pub struct Destination {
36
+ pub ( super ) alpn : Alpn ,
37
+ pub ( super ) uri : Uri ,
32
38
}
33
39
34
- impl < T > Connect for T
35
- where T : Service < Request =Uri , Error =io:: Error > + ' static ,
36
- T :: Response : AsyncRead + AsyncWrite ,
37
- T :: Future : Future < Error =io:: Error > ,
38
- {
39
- type Output = T :: Response ;
40
- type Future = T :: Future ;
40
+ /// Extra information about the connected transport.
41
+ #[ derive( Debug ) ]
42
+ pub struct Connected < T > {
43
+ alpn : Alpn ,
44
+ pub ( super ) transport : T ,
45
+ }
41
46
42
- fn connect ( & self , url : Uri ) -> <Self as Connect >:: Future {
43
- self . call ( url)
47
+ #[ derive( Debug ) ]
48
+ pub ( super ) enum Alpn {
49
+ Http1 ,
50
+ H2 ,
51
+ }
52
+
53
+ impl Destination {
54
+ /// Get a reference to the requested `Uri`.
55
+ pub fn uri ( & self ) -> & Uri {
56
+ & self . uri
57
+ }
58
+
59
+ /// Returns whether this connection must negotiate HTTP/2 via ALPN.
60
+ pub fn h2 ( & self ) -> bool {
61
+ match self . alpn {
62
+ Alpn :: Http1 => false ,
63
+ Alpn :: H2 => true ,
64
+ }
65
+ }
66
+ }
67
+
68
+ impl < T > Connected < T > {
69
+ /// Create new `Connected` type with empty metadata.
70
+ pub fn new ( transport : T ) -> Connected < T > {
71
+ Connected {
72
+ alpn : Alpn :: Http1 ,
73
+ transport : transport,
74
+ }
75
+ }
76
+
77
+ /// Convert into the underlying Transport.
78
+ pub fn into_transport ( self ) -> T {
79
+ self . transport
80
+ }
81
+
82
+ /// Set that the connected transport negotiated HTTP/2 as it's
83
+ /// next protocol.
84
+ pub fn h2 ( & mut self ) -> & mut Connected < T > {
85
+ self . alpn = Alpn :: H2 ;
86
+ self
44
87
}
45
88
}
46
89
@@ -96,6 +139,8 @@ impl fmt::Debug for HttpConnector {
96
139
}
97
140
}
98
141
142
+ // deprecated, will be gone in 0.12
143
+ #[ doc( hidden) ]
99
144
impl Service for HttpConnector {
100
145
type Request = Uri ;
101
146
type Response = TcpStream ;
@@ -258,23 +303,27 @@ impl ConnectingTcp {
258
303
}
259
304
}
260
305
261
- /// Blocking task to be executed on a thread pool.
262
- pub struct HttpConnectorBlockingTask {
263
- work : oneshot:: Execute < dns:: Work >
264
- }
306
+ // Make this Future unnameable outside of this crate.
307
+ mod http_connector {
308
+ use super :: * ;
309
+ // Blocking task to be executed on a thread pool.
310
+ pub struct HttpConnectorBlockingTask {
311
+ pub ( super ) work : oneshot:: Execute < dns:: Work >
312
+ }
265
313
266
- impl fmt:: Debug for HttpConnectorBlockingTask {
267
- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
268
- f. pad ( "HttpConnectorBlockingTask" )
314
+ impl fmt:: Debug for HttpConnectorBlockingTask {
315
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
316
+ f. pad ( "HttpConnectorBlockingTask" )
317
+ }
269
318
}
270
- }
271
319
272
- impl Future for HttpConnectorBlockingTask {
273
- type Item = ( ) ;
274
- type Error = ( ) ;
320
+ impl Future for HttpConnectorBlockingTask {
321
+ type Item = ( ) ;
322
+ type Error = ( ) ;
275
323
276
- fn poll ( & mut self ) -> Poll < ( ) , ( ) > {
277
- self . work . poll ( )
324
+ fn poll ( & mut self ) -> Poll < ( ) , ( ) > {
325
+ self . work . poll ( )
326
+ }
278
327
}
279
328
}
280
329
@@ -288,20 +337,97 @@ impl Executor<oneshot::Execute<dns::Work>> for HttpConnectExecutor {
288
337
}
289
338
}
290
339
291
- /*
292
- impl<S: SslClient> HttpsConnector<S> {
293
- /// Create a new connector using the provided SSL implementation.
294
- pub fn new(s: S) -> HttpsConnector<S> {
295
- HttpsConnector {
296
- http: HttpConnector::default(),
297
- ssl: s,
340
+ #[ doc( hidden) ]
341
+ #[ deprecated( since="0.11.16" , note="Use the Connect2 trait, which will become Connect in 0.12" ) ]
342
+ pub trait Connect : Service < Request =Uri , Error =io:: Error > + ' static {
343
+ /// The connected Io Stream.
344
+ type Output : AsyncRead + AsyncWrite + ' static ;
345
+ /// A Future that will resolve to the connected Stream.
346
+ type Future : Future < Item =Self :: Output , Error =io:: Error > + ' static ;
347
+ /// Connect to a remote address.
348
+ fn connect ( & self , Uri ) -> <Self as Connect >:: Future ;
349
+ }
350
+
351
+ #[ doc( hidden) ]
352
+ #[ allow( deprecated) ]
353
+ impl < T > Connect for T
354
+ where T : Service < Request =Uri , Error =io:: Error > + ' static ,
355
+ T :: Response : AsyncRead + AsyncWrite ,
356
+ T :: Future : Future < Error =io:: Error > ,
357
+ {
358
+ type Output = T :: Response ;
359
+ type Future = T :: Future ;
360
+
361
+ fn connect ( & self , url : Uri ) -> <Self as Connect >:: Future {
362
+ self . call ( url)
363
+ }
364
+ }
365
+
366
+ #[ doc( hidden) ]
367
+ #[ allow( deprecated) ]
368
+ impl < T > Connect2 for T
369
+ where
370
+ T : Connect ,
371
+ {
372
+ type Transport = <T as Connect >:: Output ;
373
+ type Error = io:: Error ;
374
+ type Future = ConnectToConnect2Future < <T as Connect >:: Future > ;
375
+
376
+ fn connect ( & self , dst : Destination ) -> <Self as Connect2 >:: Future {
377
+ ConnectToConnect2Future {
378
+ inner : <Self as Connect >:: connect ( self , dst. uri ) ,
298
379
}
299
380
}
300
381
}
301
- */
382
+
383
+ #[ doc( hidden) ]
384
+ #[ deprecated( since="0.11.16" ) ]
385
+ #[ allow( missing_debug_implementations) ]
386
+ pub struct ConnectToConnect2Future < F > {
387
+ inner : F ,
388
+ }
389
+
390
+ #[ allow( deprecated) ]
391
+ impl < F > Future for ConnectToConnect2Future < F >
392
+ where
393
+ F : Future ,
394
+ {
395
+ type Item = Connected < F :: Item > ;
396
+ type Error = F :: Error ;
397
+
398
+ fn poll ( & mut self ) -> Poll < Self :: Item , Self :: Error > {
399
+ self . inner . poll ( )
400
+ . map ( |async| async . map ( Connected :: new) )
401
+ }
402
+ }
403
+
404
+ // even though deprecated, we need to make sure the HttpConnector still
405
+ // implements Connect (and Service apparently...)
406
+
407
+ #[ allow( deprecated) ]
408
+ fn _assert_http_connector ( ) {
409
+ fn assert_connect < T > ( )
410
+ where
411
+ T : Connect2 <
412
+ Transport =TcpStream ,
413
+ Error =io:: Error ,
414
+ Future =ConnectToConnect2Future < HttpConnecting >
415
+ > ,
416
+ T : Connect < Output =TcpStream , Future =HttpConnecting > ,
417
+ T : Service <
418
+ Request =Uri ,
419
+ Response =TcpStream ,
420
+ Future =HttpConnecting ,
421
+ Error =io:: Error
422
+ > ,
423
+ { }
424
+
425
+ assert_connect :: < HttpConnector > ( ) ;
426
+ }
302
427
303
428
#[ cfg( test) ]
304
429
mod tests {
430
+ #![ allow( deprecated) ]
305
431
use std:: io;
306
432
use tokio:: reactor:: Core ;
307
433
use super :: { Connect , HttpConnector } ;
0 commit comments