-
Notifications
You must be signed in to change notification settings - Fork 241
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expose danger_connect_async_without_providing_domain_for_certificate_verification_and_server_name_indication #34
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,15 +56,36 @@ mod encryption { | |
-> Box<Future<Item=AutoStream<S>, Error=Error>> | ||
where | ||
S: 'static + AsyncRead + AsyncWrite, | ||
{ | ||
get_wrapped_stream(socket, domain, mode, false) | ||
} | ||
|
||
pub fn danger_wrap_stream<S>(socket: S, mode: Mode) | ||
-> Box<Future<Item=AutoStream<S>, Error=Error>> | ||
where | ||
S: 'static + AsyncRead + AsyncWrite, | ||
{ | ||
get_wrapped_stream(socket, String::new(), mode, true) | ||
} | ||
|
||
// Helper function for reducing duplicate code | ||
fn get_wrapped_stream<S>(socket: S, domain: String, mode: Mode, dangerously: bool) | ||
-> Box<Future<Item=AutoStream<S>, Error=Error>> | ||
where | ||
S: 'static + AsyncRead + AsyncWrite, | ||
{ | ||
match mode { | ||
Mode::Plain => Box::new(future::ok(StreamSwitcher::Plain(socket))), | ||
Mode::Tls => { | ||
Box::new(future::result(TlsConnector::builder()) | ||
.and_then(move |builder| future::result(builder.build())) | ||
.and_then(move |connector| connector.connect_async(&domain, socket)) | ||
.map(|s| StreamSwitcher::Tls(s)) | ||
.map_err(|e| Error::Tls(e))) | ||
.and_then(move |builder| future::result(builder.build())) | ||
.and_then(move |connector| if dangerously { | ||
connector.danger_connect_async_without_providing_domain_for_certificate_verification_and_server_name_indication(socket) | ||
} else { | ||
connector.connect_async(&domain, socket) | ||
}) | ||
.map(|s| StreamSwitcher::Tls(s)) | ||
.map_err(|e| Error::Tls(e))) | ||
} | ||
} | ||
} | ||
|
@@ -92,7 +113,7 @@ mod encryption { | |
} | ||
} | ||
|
||
use self::encryption::{AutoStream, wrap_stream}; | ||
use self::encryption::{AutoStream, wrap_stream, danger_wrap_stream}; | ||
|
||
/// Get a domain from an URL. | ||
#[inline] | ||
|
@@ -133,20 +154,55 @@ where | |
.and_then(move |stream| client_async(request, stream))) | ||
} | ||
|
||
/// Connect to a given URL. This version is dangerous. It doesn't check certificates. | ||
pub fn danger_connect_async<R>(request: R, handle: Remote) | ||
-> Box<Future<Item=(WebSocketStream<AutoStream<TcpStream>>, Response), Error=Error>> | ||
where | ||
R: Into<Request<'static>> | ||
{ | ||
connect_async_helper(request, handle, true) | ||
} | ||
|
||
|
||
/// Connect to a given URL. | ||
pub fn connect_async<R>(request: R, handle: Remote) | ||
-> Box<Future<Item=(WebSocketStream<AutoStream<TcpStream>>, Response), Error=Error>> | ||
where | ||
R: Into<Request<'static>> | ||
{ | ||
connect_async_helper(request, handle, false) | ||
} | ||
|
||
// Helper function for reducing duplicate code | ||
fn connect_async_helper<R>(request: R, handle: Remote, dangerously: bool) | ||
-> Box<Future<Item=(WebSocketStream<AutoStream<TcpStream>>, Response), Error=Error>> | ||
where | ||
R: Into<Request<'static>> | ||
{ | ||
let request: Request = request.into(); | ||
|
||
let domain = match domain(&request) { | ||
Ok(domain) => domain, | ||
Err(err) => return Box::new(future::err(err)), | ||
// Make sure we check domain and mode first. URL must be valid. | ||
let mode = match url_mode(&request.url) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This duplicates the body of |
||
Ok(m) => m, | ||
Err(e) => return Box::new(future::err(e.into())), | ||
}; | ||
let domain = match request.url.host_str() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a function which already does the same, it's called |
||
Some(d) => d.to_string(), | ||
None => return Box::new(future::err(Error::Url("No host name in the URL".into()))), | ||
}; | ||
let port = request.url.port_or_known_default().expect("Bug: port unknown"); | ||
|
||
Box::new(tcp_connect((domain.as_str(), port), handle).map_err(|e| e.into()) | ||
.and_then(move |socket| client_async_tls(request, socket))) | ||
} | ||
if dangerously { | ||
Box::new(tcp_connect((domain.as_str(), port), handle).map_err(|e| e.into()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This duplicates the body of |
||
.and_then(move |socket| danger_wrap_stream(socket, mode)) | ||
.and_then(|mut stream| { | ||
NoDelay::set_nodelay(&mut stream, true) | ||
.map(move |()| stream) | ||
.map_err(|e| e.into()) | ||
}) | ||
.and_then(move |stream| client_async(request, stream))) | ||
} else { | ||
Box::new(tcp_connect((domain.as_str(), port), handle).map_err(|e| e.into()) | ||
.and_then(move |socket| client_async_tls(request, socket))) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function, together with its additional parameter
dangerously
is actually not required. You could write it a bit simpler, by changing the signature ofwrap_stream()
a bit. Thewrap_stream()
function accepts a domain parameter, for the purpose of allowing it to perform a danger connection, you can just change the type of thedomain
fromString
toOption<String>
, in this case bothdanger_wrap_stream()
andget_wrapped_stream()
are not necessary anymore, i.e. the same thing can be rewritten shorten and simplier ;)