@ -16,27 +16,30 @@ use crate::{
protocol ::WebSocketConfig ,
} ;
#[ cfg(feature = " tls " ) ]
#[ cfg(feature = " native- tls" ) ]
mod encryption {
pub use native_tls ::TlsStream ;
use native_tls ::{ HandshakeError as TlsHandshakeError , TlsConnector } ;
pub use native_tls_crate ::TlsStream ;
use native_tls_crate ::{ HandshakeError as TlsHandshakeError , TlsConnector } ;
use std ::net ::TcpStream ;
pub use crate ::stream ::Stream as StreamSwitcher ;
/// TCP stream switcher (plain/TLS).
pub type AutoStream = StreamSwitcher < TcpStream , TlsStream < TcpStream > > ;
use crate ::{ error ::Result , stream ::Mode } ;
use crate ::{
error ::{ Result , TlsError } ,
stream ::Mode ,
} ;
pub fn wrap_stream ( stream : TcpStream , domain : & str , mode : Mode ) -> Result < AutoStream > {
match mode {
Mode ::Plain = > Ok ( StreamSwitcher ::Plain ( stream ) ) ,
Mode ::Tls = > {
let connector = TlsConnector ::builder ( ) . build ( ) ? ;
let connector = TlsConnector ::builder ( ) . build ( ) . map_err ( TlsError ::Native ) ? ;
connector
. connect ( domain , stream )
. map_err ( | e | match e {
TlsHandshakeError ::Failure ( f ) = > f . into ( ) ,
TlsHandshakeError ::Failure ( f ) = > TlsError ::Native ( f ) . into ( ) ,
TlsHandshakeError ::WouldBlock ( _ ) = > {
panic! ( "Bug: TLS handshake not blocked" )
}
@ -47,7 +50,43 @@ mod encryption {
}
}
#[ cfg(not(feature = " tls " )) ]
#[ cfg(all(feature = " rustls-tls " , not(feature = " native-tls " ))) ]
mod encryption {
use rustls ::ClientConfig ;
pub use rustls ::{ ClientSession , StreamOwned } ;
use std ::{ net ::TcpStream , sync ::Arc } ;
use webpki ::DNSNameRef ;
pub use crate ::stream ::Stream as StreamSwitcher ;
/// TCP stream switcher (plain/TLS).
pub type AutoStream = StreamSwitcher < TcpStream , StreamOwned < ClientSession , TcpStream > > ;
use crate ::{
error ::{ Result , TlsError } ,
stream ::Mode ,
} ;
pub fn wrap_stream ( stream : TcpStream , domain : & str , mode : Mode ) -> Result < AutoStream > {
match mode {
Mode ::Plain = > Ok ( StreamSwitcher ::Plain ( stream ) ) ,
Mode ::Tls = > {
let config = {
let mut config = ClientConfig ::new ( ) ;
config . root_store . add_server_trust_anchors ( & webpki_roots ::TLS_SERVER_ROOTS ) ;
Arc ::new ( config )
} ;
let domain = DNSNameRef ::try_from_ascii_str ( domain ) . map_err ( TlsError ::Dns ) ? ;
let client = ClientSession ::new ( & config , domain ) ;
let stream = StreamOwned ::new ( client , stream ) ;
Ok ( StreamSwitcher ::Tls ( stream ) )
}
}
}
}
#[ cfg(not(any(feature = " native-tls " , feature = " rustls-tls " ))) ]
mod encryption {
use std ::net ::TcpStream ;
@ -56,7 +95,7 @@ mod encryption {
stream ::Mode ,
} ;
/// TLS support is nod compiled in, this is just standard `TcpStream`.
/// TLS support is not compiled in, this is just standard `TcpStream`.
pub type AutoStream = TcpStream ;
pub fn wrap_stream ( stream : TcpStream , _domain : & str , mode : Mode ) -> Result < AutoStream > {
@ -83,15 +122,15 @@ use crate::{
/// equal to calling `connect()` function.
///
/// The URL may be either ws:// or wss://.
/// To support wss:// URLs, feature "tls" must be turned on.
/// To support wss:// URLs, feature `native-tls` or `rustls-tls` must be turned on.
///
/// This function "just works" for those who wants a simple blocking solution
/// similar to `std::net::TcpStream`. If you want a non-blocking or other
/// custom stream, call `client` instead.
///
/// This function uses `native_tls` to do TLS. If you want to use other TLS libraries,
/// use `client` instead. There is no need to enable the "tls" feature if you don't call
/// `connect` since it's the only function that uses native_tls .
/// This function uses `native_tls` or `rustls` to do TLS depending on the feature flags enabled. If
/// you want to use other TLS libraries, use `client` instead. There is no need to enable any of
/// the `*-tls` features if you don't call `connect` since it's the only function that uses them .
pub fn connect_with_config < Req : IntoClientRequest > (
request : Req ,
config : Option < WebSocketConfig > ,
@ -151,15 +190,15 @@ pub fn connect_with_config<Req: IntoClientRequest>(
/// Connect to the given WebSocket in blocking mode.
///
/// The URL may be either ws:// or wss://.
/// To support wss:// URLs, feature "tls" must be turned on.
/// To support wss:// URLs, feature `native-tls` or `rustls-tls` must be turned on.
///
/// This function "just works" for those who wants a simple blocking solution
/// similar to `std::net::TcpStream`. If you want a non-blocking or other
/// custom stream, call `client` instead.
///
/// This function uses `native_tls` to do TLS. If you want to use other TLS libraries,
/// use `client` instead. There is no need to enable the "tls" feature if you don't call
/// `connect` since it's the only function that uses native_tls .
/// This function uses `native_tls` or `rustls` to do TLS depending on the feature flags enabled. If
/// you want to use other TLS libraries, use `client` instead. There is no need to enable any of
/// the `*-tls` features if you don't call `connect` since it's the only function that uses them .
pub fn connect < Req : IntoClientRequest > ( request : Req ) -> Result < ( WebSocket < AutoStream > , Response ) > {
connect_with_config ( request , None , 3 )
}
@ -180,7 +219,7 @@ fn connect_to_some(addrs: &[SocketAddr], uri: &Uri, mode: Mode) -> Result<AutoSt
/// Get the mode of the given URL.
///
/// This function may be used to ease the creation of custom TLS streams
/// in non-blocking algorithmss or for use with TLS libraries other than `native_tls`.
/// in non-blocking algorithms or for use with TLS libraries other than `native_tls` or `rus tls`.
pub fn uri_mode ( uri : & Uri ) -> Result < Mode > {
match uri . scheme_str ( ) {
Some ( "ws" ) = > Ok ( Mode ::Plain ) ,