1+ //! Contains the `Connect2` trait, and supporting types.
12use std:: error:: Error as StdError ;
23use std:: fmt;
34use std:: io;
45use std:: mem;
56use std:: sync:: Arc ;
6- //use std::net::SocketAddr;
77
88use futures:: { Future , Poll , Async } ;
99use futures:: future:: { Executor , ExecuteError } ;
@@ -16,31 +16,74 @@ use tokio_service::Service;
1616use Uri ;
1717
1818use 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+ }
1932
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 ,
3238}
3339
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+ }
4146
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 underlyinng 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
4487 }
4588}
4689
@@ -96,6 +139,8 @@ impl fmt::Debug for HttpConnector {
96139 }
97140}
98141
142+ // deprecated, will be gone in 0.12
143+ #[ doc( hidden) ]
99144impl Service for HttpConnector {
100145 type Request = Uri ;
101146 type Response = TcpStream ;
@@ -258,23 +303,27 @@ impl ConnectingTcp {
258303 }
259304}
260305
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+ }
265313
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+ }
269318 }
270- }
271319
272- impl Future for HttpConnectorBlockingTask {
273- type Item = ( ) ;
274- type Error = ( ) ;
320+ impl Future for HttpConnectorBlockingTask {
321+ type Item = ( ) ;
322+ type Error = ( ) ;
275323
276- fn poll ( & mut self ) -> Poll < ( ) , ( ) > {
277- self . work . poll ( )
324+ fn poll ( & mut self ) -> Poll < ( ) , ( ) > {
325+ self . work . poll ( )
326+ }
278327 }
279328}
280329
@@ -288,20 +337,97 @@ impl Executor<oneshot::Execute<dns::Work>> for HttpConnectExecutor {
288337 }
289338}
290339
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 ) ,
298379 }
299380 }
300381}
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+ }
302427
303428#[ cfg( test) ]
304429mod tests {
430+ #![ allow( deprecated) ]
305431 use std:: io;
306432 use tokio:: reactor:: Core ;
307433 use super :: { Connect , HttpConnector } ;
0 commit comments