@ -90,40 +90,60 @@ pub fn connect_with_config<Req: IntoClientRequest>(
request : Req ,
config : Option < WebSocketConfig > ,
) -> Result < ( WebSocket < AutoStream > , Response ) > {
let request : Request = request . into_client_request ( ) ? ;
// Copy all the fields from the initial reqeust **except** the URI. This will be used in the event of a redirection code
// Have to manually clone Method because there is one field that contains a Box,
// but in the case of normal request methods it is Copy
let request2 = Request ::builder ( )
. method ( request . method ( ) . clone ( ) )
. version ( request . version ( ) ) ;
let uri = request . uri ( ) ;
let mode = uri_mode ( uri ) ? ;
let host = request
. uri ( )
. host ( )
. ok_or_else ( | | Error ::Url ( "No host name in the URL" . into ( ) ) ) ? ;
let port = uri . port_u16 ( ) . unwrap_or ( match mode {
Mode ::Plain = > 80 ,
Mode ::Tls = > 443 ,
} ) ;
let addrs = ( host , port ) . to_socket_addrs ( ) ? ;
let mut stream = connect_to_some ( addrs . as_slice ( ) , & request . uri ( ) , mode ) ? ;
NoDelay ::set_nodelay ( & mut stream , true ) ? ;
match client_with_config ( request , stream , config ) . map_err ( | e | match e {
HandshakeError ::Failure ( f ) = > f ,
HandshakeError ::Interrupted ( _ ) = > panic! ( "Bug: blocking handshake not blocked" ) ,
} ) {
Ok ( r ) = > Ok ( r ) ,
Err ( e ) = > match e {
Error ::Redirection ( uri ) = > {
debug ! ( "Redirecting to {}" , uri ) ;
let request = request2 . uri ( uri ) . body ( ( ) ) . unwrap ( ) ;
connect_with_config ( request , config )
let mut request : Request = request . into_client_request ( ) ? ;
fn inner ( request : Request , config : Option < WebSocketConfig > ) -> Result < ( WebSocket < AutoStream > , Response ) > {
let uri = request . uri ( ) ;
let mode = uri_mode ( uri ) ? ;
let host = request
. uri ( )
. host ( )
. ok_or_else ( | | Error ::Url ( "No host name in the URL" . into ( ) ) ) ? ;
let port = uri . port_u16 ( ) . unwrap_or ( match mode {
Mode ::Plain = > 80 ,
Mode ::Tls = > 443 ,
} ) ;
let addrs = ( host , port ) . to_socket_addrs ( ) ? ;
let mut stream = connect_to_some ( addrs . as_slice ( ) , & request . uri ( ) , mode ) ? ;
NoDelay ::set_nodelay ( & mut stream , true ) ? ;
client_with_config ( request , stream , config ) . map_err ( | e | match e {
HandshakeError ::Failure ( f ) = > f ,
HandshakeError ::Interrupted ( _ ) = > panic! ( "Bug: blocking handshake not blocked" ) ,
} )
}
let max_redirects = config . as_ref ( ) . and_then ( | c | c . max_redirects ) . unwrap_or ( 0 ) ;
let mut redirects = 0 ;
loop {
// Copy all the fields from the initial reqeust **except** the URI. This will be used in the event of a redirection code
// Have to manually clone Method because there is one field that contains a Box,
// but in the case of normal request methods it is Copy
let request2 = Request ::builder ( )
. method ( request . method ( ) . clone ( ) )
. version ( request . version ( ) ) ;
match inner ( request , config ) {
Ok ( r ) = > return Ok ( r ) ,
Err ( e ) = > match e {
Error ::Http ( res ) = > {
if res . status ( ) . is_redirection ( ) {
let uri = res . headers ( ) . get ( "Location" ) . ok_or ( Error ::NoLocation ) ? ;
debug ! ( "Redirecting to {:?}" , uri ) ;
request = request2 . uri ( uri . to_str ( ) ? . parse ::< Uri > ( ) ? ) . body ( ( ) ) . unwrap ( ) ;
redirects + = 1 ;
if redirects > max_redirects {
return Err ( Error ::Http ( res ) ) ;
}
} else {
return Err ( Error ::Http ( res ) ) ;
}
}
_ = > return Err ( e ) ,
}
_ = > Err ( e ) ,
}
}
}
/// Connect to the given WebSocket in blocking mode.