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,79 @@ 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 =( Self :: Transport , Connected ) , 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 {
43
+ alpn : Alpn ,
44
+ is_proxy : bool ,
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 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
44
92
}
45
93
}
46
94
@@ -96,6 +144,8 @@ impl fmt::Debug for HttpConnector {
96
144
}
97
145
}
98
146
147
+ // deprecated, will be gone in 0.12
148
+ #[ doc( hidden) ]
99
149
impl Service for HttpConnector {
100
150
type Request = Uri ;
101
151
type Response = TcpStream ;
@@ -258,23 +308,27 @@ impl ConnectingTcp {
258
308
}
259
309
}
260
310
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
+ }
265
318
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
+ }
269
323
}
270
- }
271
324
272
- impl Future for HttpConnectorBlockingTask {
273
- type Item = ( ) ;
274
- type Error = ( ) ;
325
+ impl Future for HttpConnectorBlockingTask {
326
+ type Item = ( ) ;
327
+ type Error = ( ) ;
275
328
276
- fn poll ( & mut self ) -> Poll < ( ) , ( ) > {
277
- self . work . poll ( )
329
+ fn poll ( & mut self ) -> Poll < ( ) , ( ) > {
330
+ self . work . poll ( )
331
+ }
278
332
}
279
333
}
280
334
@@ -288,20 +342,97 @@ impl Executor<oneshot::Execute<dns::Work>> for HttpConnectExecutor {
288
342
}
289
343
}
290
344
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 ) ,
298
384
}
299
385
}
300
386
}
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
+ }
302
432
303
433
#[ cfg( test) ]
304
434
mod tests {
435
+ #![ allow( deprecated) ]
305
436
use std:: io;
306
437
use tokio:: reactor:: Core ;
307
438
use super :: { Connect , HttpConnector } ;
0 commit comments