@@ -16,20 +16,51 @@ use actix_rt::{
1616use  actix_service:: Service ; 
1717use  actix_tls:: connect:: { 
1818    ConnectError  as  TcpConnectError ,  ConnectInfo ,  Connection  as  TcpConnection , 
19-     Connector  as  TcpConnector ,  Resolver , 
19+     Connector  as  TcpConnector ,  Host ,   Resolver , 
2020} ; 
2121use  futures_core:: { future:: LocalBoxFuture ,  ready} ; 
22- use  http:: Uri ; 
2322use  pin_project_lite:: pin_project; 
2423
2524use  super :: { 
2625    config:: ConnectorConfig , 
2726    connection:: { Connection ,  ConnectionIo } , 
2827    error:: ConnectError , 
2928    pool:: ConnectionPool , 
30-     Connect , 
29+     Connect ,   ServerName , 
3130} ; 
3231
32+ pub  enum  HostnameWithSni  { 
33+     ForTcp ( String ,  u16 ,  Option < ServerName > ) , 
34+     ForTls ( String ,  u16 ,  Option < ServerName > ) , 
35+ } 
36+ 
37+ impl  Host  for  HostnameWithSni  { 
38+     fn  hostname ( & self )  -> & str  { 
39+         match  self  { 
40+             HostnameWithSni :: ForTcp ( hostname,  _,  _)  => hostname, 
41+             HostnameWithSni :: ForTls ( hostname,  _,  sni)  => sni. as_deref ( ) . unwrap_or ( hostname) , 
42+         } 
43+     } 
44+ 
45+     fn  port ( & self )  -> Option < u16 >  { 
46+         match  self  { 
47+             HostnameWithSni :: ForTcp ( _,  port,  _)  => Some ( * port) , 
48+             HostnameWithSni :: ForTls ( _,  port,  _)  => Some ( * port) , 
49+         } 
50+     } 
51+ } 
52+ 
53+ impl  HostnameWithSni  { 
54+     pub  fn  to_tls ( self )  -> Self  { 
55+         match  self  { 
56+             HostnameWithSni :: ForTcp ( hostname,  port,  sni)  => { 
57+                 HostnameWithSni :: ForTls ( hostname,  port,  sni) 
58+             } 
59+             HostnameWithSni :: ForTls ( _,  _,  _)  => self , 
60+         } 
61+     } 
62+ } 
63+ 
3364enum  OurTlsConnector  { 
3465    #[ allow( dead_code) ]   // only dead when no TLS feature is enabled 
3566    None , 
@@ -95,8 +126,8 @@ impl Connector<()> {
95126#[ allow( clippy:: new_ret_no_self,  clippy:: let_unit_value) ]  
96127    pub  fn  new ( )  -> Connector < 
97128        impl  Service < 
98-                 ConnectInfo < Uri > , 
99-                 Response  = TcpConnection < Uri ,  TcpStream > , 
129+                 ConnectInfo < HostnameWithSni > , 
130+                 Response  = TcpConnection < HostnameWithSni ,  TcpStream > , 
100131                Error  = actix_tls:: connect:: ConnectError , 
101132            >  + Clone , 
102133    >  { 
@@ -214,8 +245,11 @@ impl<S> Connector<S> {
214245pub  fn  connector < S1 ,  Io1 > ( self ,  connector :  S1 )  -> Connector < S1 > 
215246    where 
216247        Io1 :  ActixStream  + fmt:: Debug  + ' static , 
217-         S1 :  Service < ConnectInfo < Uri > ,  Response  = TcpConnection < Uri ,  Io1 > ,  Error  = TcpConnectError > 
218-             + Clone , 
248+         S1 :  Service < 
249+                 ConnectInfo < HostnameWithSni > , 
250+                 Response  = TcpConnection < HostnameWithSni ,  Io1 > , 
251+                 Error  = TcpConnectError , 
252+             >  + Clone , 
219253    { 
220254        Connector  { 
221255            connector, 
@@ -235,8 +269,11 @@ where
235269    // This remap is to hide ActixStream's trait methods. They are not meant to be called 
236270    // from user code. 
237271    IO :  ActixStream  + fmt:: Debug  + ' static , 
238-     S :  Service < ConnectInfo < Uri > ,  Response  = TcpConnection < Uri ,  IO > ,  Error  = TcpConnectError > 
239-         + Clone 
272+     S :  Service < 
273+             ConnectInfo < HostnameWithSni > , 
274+             Response  = TcpConnection < HostnameWithSni ,  IO > , 
275+             Error  = TcpConnectError , 
276+         >  + Clone 
240277        + ' static , 
241278{ 
242279    /// Sets TCP connection timeout. 
@@ -454,7 +491,7 @@ where
454491                    use  actix_utils:: future:: { ready,  Ready } ; 
455492
456493                    #[ allow( non_local_definitions) ]  
457-                     impl  IntoConnectionIo  for  TcpConnection < Uri ,  Box < dyn  ConnectionIo > >  { 
494+                     impl  IntoConnectionIo  for  TcpConnection < HostnameWithSni ,  Box < dyn  ConnectionIo > >  { 
458495                        fn  into_connection_io ( self )  -> ( Box < dyn  ConnectionIo > ,  Protocol )  { 
459496                            let  io = self . into_parts ( ) . 0 ; 
460497                            ( io,  Protocol :: Http2 ) 
@@ -505,7 +542,7 @@ where
505542                use  actix_tls:: connect:: openssl:: { reexports:: AsyncSslStream ,  TlsConnector } ; 
506543
507544                #[ allow( non_local_definitions) ]  
508-                 impl < IO :  ConnectionIo >  IntoConnectionIo  for  TcpConnection < Uri ,  AsyncSslStream < IO > >  { 
545+                 impl < IO :  ConnectionIo >  IntoConnectionIo  for  TcpConnection < HostnameWithSni ,  AsyncSslStream < IO > >  { 
509546                    fn  into_connection_io ( self )  -> ( Box < dyn  ConnectionIo > ,  Protocol )  { 
510547                        let  sock = self . into_parts ( ) . 0 ; 
511548                        let  h2 = sock
@@ -543,7 +580,7 @@ where
543580                use  actix_tls:: connect:: rustls_0_20:: { reexports:: AsyncTlsStream ,  TlsConnector } ; 
544581
545582                #[ allow( non_local_definitions) ]  
546-                 impl < Io :  ConnectionIo >  IntoConnectionIo  for  TcpConnection < Uri ,  AsyncTlsStream < Io > >  { 
583+                 impl < Io :  ConnectionIo >  IntoConnectionIo  for  TcpConnection < HostnameWithSni ,  AsyncTlsStream < Io > >  { 
547584                    fn  into_connection_io ( self )  -> ( Box < dyn  ConnectionIo > ,  Protocol )  { 
548585                        let  sock = self . into_parts ( ) . 0 ; 
549586                        let  h2 = sock
@@ -577,7 +614,7 @@ where
577614                use  actix_tls:: connect:: rustls_0_21:: { reexports:: AsyncTlsStream ,  TlsConnector } ; 
578615
579616                #[ allow( non_local_definitions) ]  
580-                 impl < Io :  ConnectionIo >  IntoConnectionIo  for  TcpConnection < Uri ,  AsyncTlsStream < Io > >  { 
617+                 impl < Io :  ConnectionIo >  IntoConnectionIo  for  TcpConnection < HostnameWithSni ,  AsyncTlsStream < Io > >  { 
581618                    fn  into_connection_io ( self )  -> ( Box < dyn  ConnectionIo > ,  Protocol )  { 
582619                        let  sock = self . into_parts ( ) . 0 ; 
583620                        let  h2 = sock
@@ -614,7 +651,7 @@ where
614651                use  actix_tls:: connect:: rustls_0_22:: { reexports:: AsyncTlsStream ,  TlsConnector } ; 
615652
616653                #[ allow( non_local_definitions) ]  
617-                 impl < Io :  ConnectionIo >  IntoConnectionIo  for  TcpConnection < Uri ,  AsyncTlsStream < Io > >  { 
654+                 impl < Io :  ConnectionIo >  IntoConnectionIo  for  TcpConnection < HostnameWithSni ,  AsyncTlsStream < Io > >  { 
618655                    fn  into_connection_io ( self )  -> ( Box < dyn  ConnectionIo > ,  Protocol )  { 
619656                        let  sock = self . into_parts ( ) . 0 ; 
620657                        let  h2 = sock
@@ -648,7 +685,7 @@ where
648685                use  actix_tls:: connect:: rustls_0_23:: { reexports:: AsyncTlsStream ,  TlsConnector } ; 
649686
650687                #[ allow( non_local_definitions) ]  
651-                 impl < Io :  ConnectionIo >  IntoConnectionIo  for  TcpConnection < Uri ,  AsyncTlsStream < Io > >  { 
688+                 impl < Io :  ConnectionIo >  IntoConnectionIo  for  TcpConnection < HostnameWithSni ,  AsyncTlsStream < Io > >  { 
652689                    fn  into_connection_io ( self )  -> ( Box < dyn  ConnectionIo > ,  Protocol )  { 
653690                        let  sock = self . into_parts ( ) . 0 ; 
654691                        let  h2 = sock
@@ -688,15 +725,17 @@ where
688725    } 
689726} 
690727
691- /// tcp service for map `TcpConnection<Uri , Io>` type to `(Io, Protocol)` 
728+ /// tcp service for map `TcpConnection<HostnameWithSni , Io>` type to `(Io, Protocol)` 
692729#[ derive( Clone ) ]  
693730pub  struct  TcpConnectorService < S :  Clone >  { 
694731    service :  S , 
695732} 
696733
697734impl < S ,  Io >  Service < Connect >  for  TcpConnectorService < S > 
698735where 
699-     S :  Service < Connect ,  Response  = TcpConnection < Uri ,  Io > ,  Error  = ConnectError >  + Clone  + ' static , 
736+     S :  Service < Connect ,  Response  = TcpConnection < HostnameWithSni ,  Io > ,  Error  = ConnectError > 
737+         + Clone 
738+         + ' static , 
700739{ 
701740    type  Response  = ( Io ,  Protocol ) ; 
702741    type  Error  = ConnectError ; 
@@ -721,7 +760,7 @@ pin_project! {
721760
722761impl < Fut ,  Io >  Future  for  TcpConnectorFuture < Fut > 
723762where 
724-     Fut :  Future < Output  = Result < TcpConnection < Uri ,  Io > ,  ConnectError > > , 
763+     Fut :  Future < Output  = Result < TcpConnection < HostnameWithSni ,  Io > ,  ConnectError > > , 
725764{ 
726765    type  Output  = Result < ( Io ,  Protocol ) ,  ConnectError > ; 
727766
@@ -767,9 +806,10 @@ struct TlsConnectorService<Tcp, Tls> {
767806) ) ] 
768807impl < Tcp ,  Tls ,  IO >  Service < Connect >  for  TlsConnectorService < Tcp ,  Tls > 
769808where 
770-     Tcp : 
771-         Service < Connect ,  Response  = TcpConnection < Uri ,  IO > ,  Error  = ConnectError >  + Clone  + ' static , 
772-     Tls :  Service < TcpConnection < Uri ,  IO > ,  Error  = std:: io:: Error >  + Clone  + ' static , 
809+     Tcp :  Service < Connect ,  Response  = TcpConnection < HostnameWithSni ,  IO > ,  Error  = ConnectError > 
810+         + Clone 
811+         + ' static , 
812+     Tls :  Service < TcpConnection < HostnameWithSni ,  IO > ,  Error  = std:: io:: Error >  + Clone  + ' static , 
773813    Tls :: Response :  IntoConnectionIo , 
774814    IO :  ConnectionIo , 
775815{ 
@@ -822,9 +862,14 @@ trait IntoConnectionIo {
822862
823863impl < S ,  Io ,  Fut1 ,  Fut2 ,  Res >  Future  for  TlsConnectorFuture < S ,  Fut1 ,  Fut2 > 
824864where 
825-     S :  Service < TcpConnection < Uri ,  Io > ,  Response  = Res ,  Error  = std:: io:: Error ,  Future  = Fut2 > , 
865+     S :  Service < 
866+         TcpConnection < HostnameWithSni ,  Io > , 
867+         Response  = Res , 
868+         Error  = std:: io:: Error , 
869+         Future  = Fut2 , 
870+     > , 
826871    S :: Response :  IntoConnectionIo , 
827-     Fut1 :  Future < Output  = Result < TcpConnection < Uri ,  Io > ,  ConnectError > > , 
872+     Fut1 :  Future < Output  = Result < TcpConnection < HostnameWithSni ,  Io > ,  ConnectError > > , 
828873    Fut2 :  Future < Output  = Result < S :: Response ,  S :: Error > > , 
829874    Io :  ConnectionIo , 
830875{ 
@@ -838,10 +883,11 @@ where
838883                timeout, 
839884            }  => { 
840885                let  res = ready ! ( fut. poll( cx) ) ?; 
886+                 let  ( io,  hostname_with_sni)  = res. into_parts ( ) ; 
841887                let  fut = tls_service
842888                    . take ( ) 
843889                    . expect ( "TlsConnectorFuture polled after complete" ) 
844-                     . call ( res ) ; 
890+                     . call ( TcpConnection :: new ( hostname_with_sni . to_tls ( ) ,  io ) ) ; 
845891                let  timeout = sleep ( * timeout) ; 
846892                self . set ( TlsConnectorFuture :: TlsConnect  {  fut,  timeout } ) ; 
847893                self . poll ( cx) 
@@ -875,8 +921,11 @@ impl<S: Clone> TcpConnectorInnerService<S> {
875921
876922impl < S ,  Io >  Service < Connect >  for  TcpConnectorInnerService < S > 
877923where 
878-     S :  Service < ConnectInfo < Uri > ,  Response  = TcpConnection < Uri ,  Io > ,  Error  = TcpConnectError > 
879-         + Clone 
924+     S :  Service < 
925+             ConnectInfo < HostnameWithSni > , 
926+             Response  = TcpConnection < HostnameWithSni ,  Io > , 
927+             Error  = TcpConnectError , 
928+         >  + Clone 
880929        + ' static , 
881930{ 
882931    type  Response  = S :: Response ; 
@@ -886,7 +935,13 @@ where
886935    actix_service:: forward_ready!( service) ; 
887936
888937    fn  call ( & self ,  req :  Connect )  -> Self :: Future  { 
889-         let  mut  req = ConnectInfo :: new ( req. uri ) . set_addr ( req. addr ) ; 
938+         let  mut  req = ConnectInfo :: new ( HostnameWithSni :: ForTcp ( 
939+             req. hostname , 
940+             req. port , 
941+             req. sni_host , 
942+         ) ) 
943+         . set_addr ( req. addr ) 
944+         . set_port ( req. port ) ; 
890945
891946        if  let  Some ( local_addr)  = self . local_address  { 
892947            req = req. set_local_addr ( local_addr) ; 
@@ -911,9 +966,9 @@ pin_project! {
911966
912967impl < Fut ,  Io >  Future  for  TcpConnectorInnerFuture < Fut > 
913968where 
914-     Fut :  Future < Output  = Result < TcpConnection < Uri ,  Io > ,  TcpConnectError > > , 
969+     Fut :  Future < Output  = Result < TcpConnection < HostnameWithSni ,  Io > ,  TcpConnectError > > , 
915970{ 
916-     type  Output  = Result < TcpConnection < Uri ,  Io > ,  ConnectError > ; 
971+     type  Output  = Result < TcpConnection < HostnameWithSni ,  Io > ,  ConnectError > ; 
917972
918973    fn  poll ( self :  Pin < & mut  Self > ,  cx :  & mut  Context < ' _ > )  -> Poll < Self :: Output >  { 
919974        let  this = self . project ( ) ; 
@@ -973,16 +1028,17 @@ where
9731028    } 
9741029
9751030    fn  call ( & self ,  req :  Connect )  -> Self :: Future  { 
976-         match  req. uri . scheme_str ( )  { 
977-             Some ( "https" )  |  Some ( "wss" )  =>  match  self . tls_pool  { 
1031+         if  req. tls  { 
1032+             match  & self . tls_pool  { 
9781033                None  => ConnectorServiceFuture :: SslIsNotSupported , 
979-                 Some ( ref   pool)  => ConnectorServiceFuture :: Tls  { 
1034+                 Some ( pool)  => ConnectorServiceFuture :: Tls  { 
9801035                    fut :  pool. call ( req) , 
9811036                } , 
982-             } , 
983-             _ => ConnectorServiceFuture :: Tcp  { 
1037+             } 
1038+         }  else  { 
1039+             ConnectorServiceFuture :: Tcp  { 
9841040                fut :  self . tcp_pool . call ( req) , 
985-             } , 
1041+             } 
9861042        } 
9871043    } 
9881044} 
0 commit comments