use std::io;
use std::net::TcpStream;
use hyper::error::Result;
use hyper::net::{HttpStream, HttpsStream, NetworkConnector, SslClient};
pub struct ClickSslConnector<S: SslClient> {
ssl: S,
host_addr: Option<(String, String)>,
}
impl<S: SslClient> ClickSslConnector<S> {
pub fn new(s: S, host_addr: Option<(String, String)>) -> ClickSslConnector<S> {
ClickSslConnector {
ssl: s,
host_addr: host_addr,
}
}
fn click_connect(&self, host: &str, port: u16, scheme: &str) -> Result<HttpStream> {
let addr = match self.host_addr {
Some((ref target_host, ref ip)) => {
if host == target_host {
(ip.as_str(), port)
} else {
(host, port)
}
}
None => (host, port),
};
Ok(try!(match scheme {
"http" => {
let res = Ok(HttpStream(try!(TcpStream::connect(&addr))));
res
}
_ => Err(io::Error::new(
io::ErrorKind::InvalidInput,
"Invalid scheme for Http"
)),
}))
}
}
impl<S: SslClient> NetworkConnector for ClickSslConnector<S> {
type Stream = HttpsStream<S::Stream>;
fn connect(&self, host: &str, port: u16, scheme: &str) -> Result<Self::Stream> {
let stream = try!(self.click_connect(host, port, "http"));
if scheme == "https" {
self.ssl.wrap_client(stream, host).map(HttpsStream::Https)
} else {
Ok(HttpsStream::Http(stream))
}
}
}