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,79 @@ 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 =( Self :: Transport , Connected ) , 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 {
43+ alpn : Alpn ,
44+ is_proxy : bool ,
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 Connected {
69+ /// Create new `Connected` type with empty metadata.
70+ pub fn new ( ) -> Connected {
71+ Connected {
72+ alpn : Alpn :: Http1 ,
73+ is_proxy : false ,
74+ }
75+ }
76+
77+ /// Set that the connected transport is to an HTTP proxy.
78+ ///
79+ /// This setting will affect if HTTP/1 requests written on the transport
80+ /// will have the request-target in absolute-form or origin-form (such as
81+ /// `GET http://hyper.rs/guide HTTP/1.1` or `GET /guide HTTP/1.1`).
82+ pub fn proxy ( mut self ) -> Connected {
83+ self . is_proxy = true ;
84+ self
85+ }
86+
87+ /// Set that the connected transport negotiated HTTP/2 as it's
88+ /// next protocol.
89+ pub fn h2 ( mut self ) -> Connected {
90+ self . alpn = Alpn :: H2 ;
91+ self
4492 }
4593}
4694
@@ -96,6 +144,8 @@ impl fmt::Debug for HttpConnector {
96144 }
97145}
98146
147+ // deprecated, will be gone in 0.12
148+ #[ doc( hidden) ]
99149impl Service for HttpConnector {
100150 type Request = Uri ;
101151 type Response = TcpStream ;
@@ -258,23 +308,27 @@ impl ConnectingTcp {
258308 }
259309}
260310
261- /// Blocking task to be executed on a thread pool.
262- pub struct HttpConnectorBlockingTask {
263- work : oneshot:: Execute < dns:: Work >
264- }
311+ // Make this Future unnameable outside of this crate.
312+ mod http_connector {
313+ use super :: * ;
314+ // Blocking task to be executed on a thread pool.
315+ pub struct HttpConnectorBlockingTask {
316+ pub ( super ) work : oneshot:: Execute < dns:: Work >
317+ }
265318
266- impl fmt:: Debug for HttpConnectorBlockingTask {
267- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
268- f. pad ( "HttpConnectorBlockingTask" )
319+ impl fmt:: Debug for HttpConnectorBlockingTask {
320+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
321+ f. pad ( "HttpConnectorBlockingTask" )
322+ }
269323 }
270- }
271324
272- impl Future for HttpConnectorBlockingTask {
273- type Item = ( ) ;
274- type Error = ( ) ;
325+ impl Future for HttpConnectorBlockingTask {
326+ type Item = ( ) ;
327+ type Error = ( ) ;
275328
276- fn poll ( & mut self ) -> Poll < ( ) , ( ) > {
277- self . work . poll ( )
329+ fn poll ( & mut self ) -> Poll < ( ) , ( ) > {
330+ self . work . poll ( )
331+ }
278332 }
279333}
280334
@@ -288,20 +342,97 @@ impl Executor<oneshot::Execute<dns::Work>> for HttpConnectExecutor {
288342 }
289343}
290344
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,
345+ #[ doc( hidden) ]
346+ #[ deprecated( since="0.11.16" , note="Use the Connect2 trait, which will become Connect in 0.12" ) ]
347+ pub trait Connect : Service < Request =Uri , Error =io:: Error > + ' static {
348+ /// The connected Io Stream.
349+ type Output : AsyncRead + AsyncWrite + ' static ;
350+ /// A Future that will resolve to the connected Stream.
351+ type Future : Future < Item =Self :: Output , Error =io:: Error > + ' static ;
352+ /// Connect to a remote address.
353+ fn connect ( & self , Uri ) -> <Self as Connect >:: Future ;
354+ }
355+
356+ #[ doc( hidden) ]
357+ #[ allow( deprecated) ]
358+ impl < T > Connect for T
359+ where T : Service < Request =Uri , Error =io:: Error > + ' static ,
360+ T :: Response : AsyncRead + AsyncWrite ,
361+ T :: Future : Future < Error =io:: Error > ,
362+ {
363+ type Output = T :: Response ;
364+ type Future = T :: Future ;
365+
366+ fn connect ( & self , url : Uri ) -> <Self as Connect >:: Future {
367+ self . call ( url)
368+ }
369+ }
370+
371+ #[ doc( hidden) ]
372+ #[ allow( deprecated) ]
373+ impl < T > Connect2 for T
374+ where
375+ T : Connect ,
376+ {
377+ type Transport = <T as Connect >:: Output ;
378+ type Error = io:: Error ;
379+ type Future = ConnectToConnect2Future < <T as Connect >:: Future > ;
380+
381+ fn connect ( & self , dst : Destination ) -> <Self as Connect2 >:: Future {
382+ ConnectToConnect2Future {
383+ inner : <Self as Connect >:: connect ( self , dst. uri ) ,
298384 }
299385 }
300386}
301- */
387+
388+ #[ doc( hidden) ]
389+ #[ deprecated( since="0.11.16" ) ]
390+ #[ allow( missing_debug_implementations) ]
391+ pub struct ConnectToConnect2Future < F > {
392+ inner : F ,
393+ }
394+
395+ #[ allow( deprecated) ]
396+ impl < F > Future for ConnectToConnect2Future < F >
397+ where
398+ F : Future ,
399+ {
400+ type Item = ( F :: Item , Connected ) ;
401+ type Error = F :: Error ;
402+
403+ fn poll ( & mut self ) -> Poll < Self :: Item , Self :: Error > {
404+ self . inner . poll ( )
405+ . map ( |async| async . map ( |t| ( t, Connected :: new ( ) ) ) )
406+ }
407+ }
408+
409+ // even though deprecated, we need to make sure the HttpConnector still
410+ // implements Connect (and Service apparently...)
411+
412+ #[ allow( deprecated) ]
413+ fn _assert_http_connector ( ) {
414+ fn assert_connect < T > ( )
415+ where
416+ T : Connect2 <
417+ Transport =TcpStream ,
418+ Error =io:: Error ,
419+ Future =ConnectToConnect2Future < HttpConnecting >
420+ > ,
421+ T : Connect < Output =TcpStream , Future =HttpConnecting > ,
422+ T : Service <
423+ Request =Uri ,
424+ Response =TcpStream ,
425+ Future =HttpConnecting ,
426+ Error =io:: Error
427+ > ,
428+ { }
429+
430+ assert_connect :: < HttpConnector > ( ) ;
431+ }
302432
303433#[ cfg( test) ]
304434mod tests {
435+ #![ allow( deprecated) ]
305436 use std:: io;
306437 use tokio:: reactor:: Core ;
307438 use super :: { Connect , HttpConnector } ;
0 commit comments