11use futures_util:: FutureExt ;
2- use hyper:: client:: connect:: { self , Connect } ;
32#[ cfg( feature = "tokio-runtime" ) ]
4- use hyper:: client:: HttpConnector ;
5- use rustls:: { ClientConfig , Session } ;
3+ use hyper:: client:: connect:: HttpConnector ;
4+ use hyper:: { client:: connect:: Connection , service:: Service , Uri } ;
5+ use rustls:: ClientConfig ;
66use std:: future:: Future ;
77use std:: pin:: Pin ;
88use std:: sync:: Arc ;
9+ use std:: task:: { Context , Poll } ;
910use std:: { fmt, io} ;
11+ use tokio:: io:: { AsyncRead , AsyncWrite } ;
1012use tokio_rustls:: TlsConnector ;
1113use webpki:: DNSNameRef ;
1214
1315use crate :: stream:: MaybeHttpsStream ;
1416
17+ type BoxError = Box < dyn std:: error:: Error + Send + Sync > ;
18+
1519/// A Connector for the `https` scheme.
1620#[ derive( Clone ) ]
1721pub struct HttpsConnector < T > {
@@ -28,8 +32,8 @@ impl HttpsConnector<HttpConnector> {
2832 let mut http = HttpConnector :: new ( ) ;
2933 http. enforce_http ( false ) ;
3034 let mut config = ClientConfig :: new ( ) ;
31- config. root_store = rustls_native_certs :: load_native_certs ( )
32- . expect ( "cannot access native cert store" ) ;
35+ config. root_store =
36+ rustls_native_certs :: load_native_certs ( ) . expect ( "cannot access native cert store" ) ;
3337 config. ct_logs = Some ( & ct_logs:: LOGS ) ;
3438 HttpsConnector {
3539 http,
@@ -69,59 +73,55 @@ impl<T> From<(T, Arc<ClientConfig>)> for HttpsConnector<T> {
6973 }
7074}
7175
72- impl < T > Connect for HttpsConnector < T >
76+ impl < T > Service < Uri > for HttpsConnector < T >
7377where
74- T : Connect < Error = io:: Error > ,
75- T :: Transport : ' static ,
76- T :: Future : ' static ,
78+ T : Service < Uri > ,
79+ T :: Response : Connection + AsyncRead + AsyncWrite + Send + Unpin + ' static ,
80+ T :: Future : Send + ' static ,
81+ T :: Error : Into < BoxError > ,
7782{
78- type Transport = MaybeHttpsStream < T :: Transport > ;
79- type Error = io :: Error ;
83+ type Response = MaybeHttpsStream < T :: Response > ;
84+ type Error = BoxError ;
8085
8186 #[ allow( clippy:: type_complexity) ]
82- type Future = Pin <
83- Box <
84- dyn Future <
85- Output = Result <
86- ( MaybeHttpsStream < T :: Transport > , connect :: Connected ) ,
87- io :: Error ,
88- > ,
89- > + Send ,
90- > ,
91- > ;
92-
93- fn connect ( & self , dst : connect :: Destination ) -> Self :: Future {
94- let is_https = dst. scheme ( ) == "https" ;
87+ type Future =
88+ Pin < Box < dyn Future < Output = Result < MaybeHttpsStream < T :: Response > , BoxError > > + Send > > ;
89+
90+ fn poll_ready ( & mut self , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) , Self :: Error > > {
91+ match self . http . poll_ready ( cx ) {
92+ Poll :: Ready ( Ok ( ( ) ) ) => Poll :: Ready ( Ok ( ( ) ) ) ,
93+ Poll :: Ready ( Err ( e ) ) => Poll :: Ready ( Err ( e . into ( ) ) ) ,
94+ Poll :: Pending => Poll :: Pending ,
95+ }
96+ }
97+
98+ fn call ( & mut self , dst : Uri ) -> Self :: Future {
99+ let is_https = dst. scheme_str ( ) == Some ( "https" ) ;
95100
96101 if !is_https {
97- let connecting_future = self . http . connect ( dst) ;
102+ let connecting_future = self . http . call ( dst) ;
98103
99104 let f = async move {
100- let ( tcp, conn ) = connecting_future. await ?;
105+ let tcp = connecting_future. await . map_err ( Into :: into ) ?;
101106
102- Ok ( ( MaybeHttpsStream :: Http ( tcp) , conn ) )
107+ Ok ( MaybeHttpsStream :: Http ( tcp) )
103108 } ;
104109 f. boxed ( )
105110 } else {
106111 let cfg = self . tls_config . clone ( ) ;
107- let hostname = dst. host ( ) . to_string ( ) ;
108- let connecting_future = self . http . connect ( dst) ;
112+ let hostname = dst. host ( ) . unwrap_or_default ( ) . to_string ( ) ;
113+ let connecting_future = self . http . call ( dst) ;
109114
110115 let f = async move {
111- let ( tcp, conn ) = connecting_future. await ?;
116+ let tcp = connecting_future. await . map_err ( Into :: into ) ?;
112117 let connector = TlsConnector :: from ( cfg) ;
113118 let dnsname = DNSNameRef :: try_from_ascii_str ( & hostname)
114119 . map_err ( |_| io:: Error :: new ( io:: ErrorKind :: Other , "invalid dnsname" ) ) ?;
115120 let tls = connector
116121 . connect ( dnsname, tcp)
117122 . await
118123 . map_err ( |e| io:: Error :: new ( io:: ErrorKind :: Other , e) ) ?;
119- let connected = if tls. get_ref ( ) . 1 . get_alpn_protocol ( ) == Some ( b"h2" ) {
120- conn. negotiated_h2 ( )
121- } else {
122- conn
123- } ;
124- Ok ( ( MaybeHttpsStream :: Https ( tls) , connected) )
124+ Ok ( MaybeHttpsStream :: Https ( tls) )
125125 } ;
126126 f. boxed ( )
127127 }
0 commit comments