@@ -23,11 +23,13 @@ use hyper::header::{
2323 ProtocolName ,
2424} ;
2525use unicase:: UniCase ;
26- use openssl:: ssl :: error:: SslError ;
26+ use openssl:: error:: ErrorStack as SslError ;
2727use openssl:: ssl:: {
2828 SslContext ,
2929 SslMethod ,
3030 SslStream ,
31+ SslConnector ,
32+ SslConnectorBuilder ,
3133} ;
3234use header:: extensions:: Extension ;
3335use header:: {
@@ -73,23 +75,21 @@ macro_rules! upsert_header {
7375
7476/// Build clients with a builder-style API
7577#[ derive( Clone , Debug ) ]
76- pub struct ClientBuilder < ' u , ' s > {
78+ pub struct ClientBuilder < ' u > {
7779 url : Cow < ' u , Url > ,
7880 version : HttpVersion ,
7981 headers : Headers ,
8082 version_set : bool ,
8183 key_set : bool ,
82- ssl_context : Option < Cow < ' s , SslContext > > ,
8384}
8485
85- impl < ' u , ' s > ClientBuilder < ' u , ' s > {
86+ impl < ' u > ClientBuilder < ' u > {
8687 pub fn new ( url : Cow < ' u , Url > ) -> Self {
8788 ClientBuilder {
8889 url : url,
8990 version : HttpVersion :: Http11 ,
9091 version_set : false ,
9192 key_set : false ,
92- ssl_context : None ,
9393 headers : Headers :: new ( ) ,
9494 }
9595 }
@@ -184,11 +184,6 @@ impl<'u, 's> ClientBuilder<'u, 's> {
184184 self
185185 }
186186
187- pub fn ssl_context ( mut self , context : & ' s SslContext ) -> Self {
188- self . ssl_context = Some ( Cow :: Borrowed ( context) ) ;
189- self
190- }
191-
192187 fn establish_tcp ( & mut self , secure : Option < bool > ) -> WebSocketResult < TcpStream > {
193188 let port = match ( self . url . port ( ) , secure) {
194189 ( Some ( port) , _) => port,
@@ -206,20 +201,30 @@ impl<'u, 's> ClientBuilder<'u, 's> {
206201 Ok ( tcp_stream)
207202 }
208203
209- fn wrap_ssl ( & self , tcp_stream : TcpStream ) -> Result < SslStream < TcpStream > , SslError > {
210- let context = match self . ssl_context {
211- Some ( ref ctx) => Cow :: Borrowed ( ctx. as_ref ( ) ) ,
212- None => Cow :: Owned ( try!( SslContext :: new ( SslMethod :: Tlsv1 ) ) ) ,
204+ fn wrap_ssl ( & self ,
205+ tcp_stream : TcpStream ,
206+ connector : Option < SslConnector >
207+ ) -> WebSocketResult < SslStream < TcpStream > > {
208+ let host = match self . url . host_str ( ) {
209+ Some ( h) => h,
210+ None => return Err ( WebSocketError :: WebSocketUrlError ( WSUrlErrorKind :: NoHostName ) ) ,
211+ } ;
212+ let connector = match connector {
213+ Some ( c) => c,
214+ None => try!( SslConnectorBuilder :: new ( SslMethod :: tls ( ) ) ) . build ( ) ,
213215 } ;
214216
215- SslStream :: connect ( & * context, tcp_stream)
217+ let ssl_stream = try!( connector. connect ( host, tcp_stream) ) ;
218+ Ok ( ssl_stream)
216219 }
217220
218- pub fn connect ( & mut self ) -> WebSocketResult < Client < BoxedNetworkStream > > {
221+ pub fn connect ( & mut self ,
222+ ssl_config : Option < SslConnector >
223+ ) -> WebSocketResult < Client < BoxedNetworkStream > > {
219224 let tcp_stream = try!( self . establish_tcp ( None ) ) ;
220225
221226 let boxed_stream = if self . url . scheme ( ) == "wss" {
222- BoxedNetworkStream ( Box :: new ( try!( self . wrap_ssl ( tcp_stream) ) ) )
227+ BoxedNetworkStream ( Box :: new ( try!( self . wrap_ssl ( tcp_stream, ssl_config ) ) ) )
223228 } else {
224229 BoxedNetworkStream ( Box :: new ( tcp_stream) )
225230 } ;
@@ -233,10 +238,12 @@ impl<'u, 's> ClientBuilder<'u, 's> {
233238 self . connect_on ( tcp_stream)
234239 }
235240
236- pub fn connect_secure ( & mut self ) -> WebSocketResult < Client < SslStream < TcpStream > > > {
241+ pub fn connect_secure ( & mut self ,
242+ ssl_config : Option < SslConnector >
243+ ) -> WebSocketResult < Client < SslStream < TcpStream > > > {
237244 let tcp_stream = try!( self . establish_tcp ( Some ( true ) ) ) ;
238245
239- let ssl_stream = try!( self . wrap_ssl ( tcp_stream) ) ;
246+ let ssl_stream = try!( self . wrap_ssl ( tcp_stream, ssl_config ) ) ;
240247
241248 self . connect_on ( ssl_stream)
242249 }
@@ -291,7 +298,7 @@ impl<'u, 's> ClientBuilder<'u, 's> {
291298 WebSocketError :: RequestError ( "Request Sec-WebSocket-Key was invalid" )
292299 ) ) ;
293300
294- if response. headers . get ( ) != Some ( & ( WebSocketAccept :: new ( key) ) ) {
301+ if response. headers . get ( ) != Some ( & ( try! ( WebSocketAccept :: new ( key) ) ) ) {
295302 return Err ( WebSocketError :: ResponseError ( "Sec-WebSocket-Accept is invalid" ) ) ;
296303 }
297304
0 commit comments