@@ -16,20 +16,51 @@ use actix_rt::{
16
16
use actix_service:: Service ;
17
17
use actix_tls:: connect:: {
18
18
ConnectError as TcpConnectError , ConnectInfo , Connection as TcpConnection ,
19
- Connector as TcpConnector , Resolver ,
19
+ Connector as TcpConnector , Host , Resolver ,
20
20
} ;
21
21
use futures_core:: { future:: LocalBoxFuture , ready} ;
22
- use http:: Uri ;
23
22
use pin_project_lite:: pin_project;
24
23
25
24
use super :: {
26
25
config:: ConnectorConfig ,
27
26
connection:: { Connection , ConnectionIo } ,
28
27
error:: ConnectError ,
29
28
pool:: ConnectionPool ,
30
- Connect ,
29
+ Connect , ServerName ,
31
30
} ;
32
31
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
+
33
64
enum OurTlsConnector {
34
65
#[ allow( dead_code) ] // only dead when no TLS feature is enabled
35
66
None ,
@@ -95,8 +126,8 @@ impl Connector<()> {
95
126
#[ allow( clippy:: new_ret_no_self, clippy:: let_unit_value) ]
96
127
pub fn new ( ) -> Connector <
97
128
impl Service <
98
- ConnectInfo < Uri > ,
99
- Response = TcpConnection < Uri , TcpStream > ,
129
+ ConnectInfo < HostnameWithSni > ,
130
+ Response = TcpConnection < HostnameWithSni , TcpStream > ,
100
131
Error = actix_tls:: connect:: ConnectError ,
101
132
> + Clone ,
102
133
> {
@@ -214,8 +245,11 @@ impl<S> Connector<S> {
214
245
pub fn connector < S1 , Io1 > ( self , connector : S1 ) -> Connector < S1 >
215
246
where
216
247
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 ,
219
253
{
220
254
Connector {
221
255
connector,
@@ -235,8 +269,11 @@ where
235
269
// This remap is to hide ActixStream's trait methods. They are not meant to be called
236
270
// from user code.
237
271
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
240
277
+ ' static ,
241
278
{
242
279
/// Sets TCP connection timeout.
@@ -454,7 +491,7 @@ where
454
491
use actix_utils:: future:: { ready, Ready } ;
455
492
456
493
#[ allow( non_local_definitions) ]
457
- impl IntoConnectionIo for TcpConnection < Uri , Box < dyn ConnectionIo > > {
494
+ impl IntoConnectionIo for TcpConnection < HostnameWithSni , Box < dyn ConnectionIo > > {
458
495
fn into_connection_io ( self ) -> ( Box < dyn ConnectionIo > , Protocol ) {
459
496
let io = self . into_parts ( ) . 0 ;
460
497
( io, Protocol :: Http2 )
@@ -505,7 +542,7 @@ where
505
542
use actix_tls:: connect:: openssl:: { reexports:: AsyncSslStream , TlsConnector } ;
506
543
507
544
#[ allow( non_local_definitions) ]
508
- impl < IO : ConnectionIo > IntoConnectionIo for TcpConnection < Uri , AsyncSslStream < IO > > {
545
+ impl < IO : ConnectionIo > IntoConnectionIo for TcpConnection < HostnameWithSni , AsyncSslStream < IO > > {
509
546
fn into_connection_io ( self ) -> ( Box < dyn ConnectionIo > , Protocol ) {
510
547
let sock = self . into_parts ( ) . 0 ;
511
548
let h2 = sock
@@ -543,7 +580,7 @@ where
543
580
use actix_tls:: connect:: rustls_0_20:: { reexports:: AsyncTlsStream , TlsConnector } ;
544
581
545
582
#[ allow( non_local_definitions) ]
546
- impl < Io : ConnectionIo > IntoConnectionIo for TcpConnection < Uri , AsyncTlsStream < Io > > {
583
+ impl < Io : ConnectionIo > IntoConnectionIo for TcpConnection < HostnameWithSni , AsyncTlsStream < Io > > {
547
584
fn into_connection_io ( self ) -> ( Box < dyn ConnectionIo > , Protocol ) {
548
585
let sock = self . into_parts ( ) . 0 ;
549
586
let h2 = sock
@@ -577,7 +614,7 @@ where
577
614
use actix_tls:: connect:: rustls_0_21:: { reexports:: AsyncTlsStream , TlsConnector } ;
578
615
579
616
#[ allow( non_local_definitions) ]
580
- impl < Io : ConnectionIo > IntoConnectionIo for TcpConnection < Uri , AsyncTlsStream < Io > > {
617
+ impl < Io : ConnectionIo > IntoConnectionIo for TcpConnection < HostnameWithSni , AsyncTlsStream < Io > > {
581
618
fn into_connection_io ( self ) -> ( Box < dyn ConnectionIo > , Protocol ) {
582
619
let sock = self . into_parts ( ) . 0 ;
583
620
let h2 = sock
@@ -614,7 +651,7 @@ where
614
651
use actix_tls:: connect:: rustls_0_22:: { reexports:: AsyncTlsStream , TlsConnector } ;
615
652
616
653
#[ allow( non_local_definitions) ]
617
- impl < Io : ConnectionIo > IntoConnectionIo for TcpConnection < Uri , AsyncTlsStream < Io > > {
654
+ impl < Io : ConnectionIo > IntoConnectionIo for TcpConnection < HostnameWithSni , AsyncTlsStream < Io > > {
618
655
fn into_connection_io ( self ) -> ( Box < dyn ConnectionIo > , Protocol ) {
619
656
let sock = self . into_parts ( ) . 0 ;
620
657
let h2 = sock
@@ -648,7 +685,7 @@ where
648
685
use actix_tls:: connect:: rustls_0_23:: { reexports:: AsyncTlsStream , TlsConnector } ;
649
686
650
687
#[ allow( non_local_definitions) ]
651
- impl < Io : ConnectionIo > IntoConnectionIo for TcpConnection < Uri , AsyncTlsStream < Io > > {
688
+ impl < Io : ConnectionIo > IntoConnectionIo for TcpConnection < HostnameWithSni , AsyncTlsStream < Io > > {
652
689
fn into_connection_io ( self ) -> ( Box < dyn ConnectionIo > , Protocol ) {
653
690
let sock = self . into_parts ( ) . 0 ;
654
691
let h2 = sock
@@ -688,15 +725,17 @@ where
688
725
}
689
726
}
690
727
691
- /// tcp service for map `TcpConnection<Uri , Io>` type to `(Io, Protocol)`
728
+ /// tcp service for map `TcpConnection<HostnameWithSni , Io>` type to `(Io, Protocol)`
692
729
#[ derive( Clone ) ]
693
730
pub struct TcpConnectorService < S : Clone > {
694
731
service : S ,
695
732
}
696
733
697
734
impl < S , Io > Service < Connect > for TcpConnectorService < S >
698
735
where
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 ,
700
739
{
701
740
type Response = ( Io , Protocol ) ;
702
741
type Error = ConnectError ;
@@ -721,7 +760,7 @@ pin_project! {
721
760
722
761
impl < Fut , Io > Future for TcpConnectorFuture < Fut >
723
762
where
724
- Fut : Future < Output = Result < TcpConnection < Uri , Io > , ConnectError > > ,
763
+ Fut : Future < Output = Result < TcpConnection < HostnameWithSni , Io > , ConnectError > > ,
725
764
{
726
765
type Output = Result < ( Io , Protocol ) , ConnectError > ;
727
766
@@ -767,9 +806,10 @@ struct TlsConnectorService<Tcp, Tls> {
767
806
) ) ]
768
807
impl < Tcp , Tls , IO > Service < Connect > for TlsConnectorService < Tcp , Tls >
769
808
where
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 ,
773
813
Tls :: Response : IntoConnectionIo ,
774
814
IO : ConnectionIo ,
775
815
{
@@ -822,9 +862,14 @@ trait IntoConnectionIo {
822
862
823
863
impl < S , Io , Fut1 , Fut2 , Res > Future for TlsConnectorFuture < S , Fut1 , Fut2 >
824
864
where
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
+ > ,
826
871
S :: Response : IntoConnectionIo ,
827
- Fut1 : Future < Output = Result < TcpConnection < Uri , Io > , ConnectError > > ,
872
+ Fut1 : Future < Output = Result < TcpConnection < HostnameWithSni , Io > , ConnectError > > ,
828
873
Fut2 : Future < Output = Result < S :: Response , S :: Error > > ,
829
874
Io : ConnectionIo ,
830
875
{
@@ -838,10 +883,11 @@ where
838
883
timeout,
839
884
} => {
840
885
let res = ready ! ( fut. poll( cx) ) ?;
886
+ let ( io, hostname_with_sni) = res. into_parts ( ) ;
841
887
let fut = tls_service
842
888
. take ( )
843
889
. expect ( "TlsConnectorFuture polled after complete" )
844
- . call ( res ) ;
890
+ . call ( TcpConnection :: new ( hostname_with_sni . to_tls ( ) , io ) ) ;
845
891
let timeout = sleep ( * timeout) ;
846
892
self . set ( TlsConnectorFuture :: TlsConnect { fut, timeout } ) ;
847
893
self . poll ( cx)
@@ -875,8 +921,11 @@ impl<S: Clone> TcpConnectorInnerService<S> {
875
921
876
922
impl < S , Io > Service < Connect > for TcpConnectorInnerService < S >
877
923
where
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
880
929
+ ' static ,
881
930
{
882
931
type Response = S :: Response ;
@@ -886,7 +935,13 @@ where
886
935
actix_service:: forward_ready!( service) ;
887
936
888
937
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 ) ;
890
945
891
946
if let Some ( local_addr) = self . local_address {
892
947
req = req. set_local_addr ( local_addr) ;
@@ -911,9 +966,9 @@ pin_project! {
911
966
912
967
impl < Fut , Io > Future for TcpConnectorInnerFuture < Fut >
913
968
where
914
- Fut : Future < Output = Result < TcpConnection < Uri , Io > , TcpConnectError > > ,
969
+ Fut : Future < Output = Result < TcpConnection < HostnameWithSni , Io > , TcpConnectError > > ,
915
970
{
916
- type Output = Result < TcpConnection < Uri , Io > , ConnectError > ;
971
+ type Output = Result < TcpConnection < HostnameWithSni , Io > , ConnectError > ;
917
972
918
973
fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
919
974
let this = self . project ( ) ;
@@ -973,16 +1028,17 @@ where
973
1028
}
974
1029
975
1030
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 {
978
1033
None => ConnectorServiceFuture :: SslIsNotSupported ,
979
- Some ( ref pool) => ConnectorServiceFuture :: Tls {
1034
+ Some ( pool) => ConnectorServiceFuture :: Tls {
980
1035
fut : pool. call ( req) ,
981
1036
} ,
982
- } ,
983
- _ => ConnectorServiceFuture :: Tcp {
1037
+ }
1038
+ } else {
1039
+ ConnectorServiceFuture :: Tcp {
984
1040
fut : self . tcp_pool . call ( req) ,
985
- } ,
1041
+ }
986
1042
}
987
1043
}
988
1044
}
0 commit comments