Skip to content

Commit

Permalink
allow choose a backend at runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
quininer committed Nov 22, 2018
1 parent 70778f3 commit 2d1c4c7
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 232 deletions.
96 changes: 50 additions & 46 deletions src/async_impl/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use into_url::to_uri;
use redirect::{self, RedirectPolicy, remove_sensitive_headers};
use {IntoUrl, Method, Proxy, StatusCode, Url};
#[cfg(feature = "tls")]
use {Certificate, Identity};
use {Certificate, Identity, tls::TlsBackend};

static DEFAULT_USER_AGENT: &'static str =
concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"));
Expand Down Expand Up @@ -52,10 +52,12 @@ struct Config {
redirect_policy: RedirectPolicy,
referer: bool,
timeout: Option<Duration>,
#[cfg(feature = "default-tls")]
tls: TlsConnectorBuilder,
#[cfg(feature = "rustls-tls")]
tls: rustls::ClientConfig,
#[cfg(feature = "tls")]
root_certs: Vec<Certificate>,
#[cfg(feature = "tls")]
identity: Vec<Identity>,
#[cfg(feature = "tls")]
tls: Option<TlsBackend>,
dns_threads: usize,
}

Expand All @@ -78,14 +80,12 @@ impl ClientBuilder {
redirect_policy: RedirectPolicy::default(),
referer: true,
timeout: None,
#[cfg(feature = "default-tls")]
tls: TlsConnector::builder(),
#[cfg(feature = "rustls-tls")]
tls: {
let mut tls = rustls::ClientConfig::new();
tls.root_store.add_server_trust_anchors(&::webpki_roots::TLS_SERVER_ROOTS);
tls
},
#[cfg(feature = "tls")]
root_certs: Vec::new(),
#[cfg(feature = "tls")]
identity: Vec::new(),
#[cfg(feature = "tls")]
tls: None,
dns_threads: 4,
},
}
Expand All @@ -99,30 +99,39 @@ impl ClientBuilder {
pub fn build(self) -> ::Result<Client> {
let config = self.config;


let connector = {
#[cfg(feature = "default-tls")]
#[cfg(feature = "tls")]
{
let mut tls = config.tls;
tls.danger_accept_invalid_hostnames(!config.hostname_verification);
tls.danger_accept_invalid_certs(!config.certs_verification);
let tls = config.tls.unwrap_or_default();
let tls = match tls {
#[cfg(feature = "default-tls")]
TlsBackend::Default(mut tls) => {
tls.danger_accept_invalid_hostnames(!config.hostname_verification);
tls.danger_accept_invalid_certs(!config.certs_verification);

let tls = try_!(tls.build());
// TODO
// add root_certs
// add identity

let proxies = Arc::new(config.proxies);
TlsBackend::Default(tls)
},
#[cfg(feature = "rustls-tls")]
TlsBackend::Rustls(mut tls) => {
// TODO
// danger accept
// add root_certs
// add identity

Connector::new(config.dns_threads, tls, proxies.clone())
}
TlsBackend::Rustls(tls)
}
};

#[cfg(feature = "rustls-tls")]
{
let tls = config.tls;
let proxies = Arc::new(config.proxies);

Connector::new(config.dns_threads, tls, proxies.clone())
Connector::new(config.dns_threads, tls, proxies.clone())?
}

#[cfg(not(any(feature = "default-tls", feature = "rustls-tls")))]
#[cfg(not(feature = "tls"))]
{
let proxies = Arc::new(config.proxies);

Expand All @@ -144,39 +153,34 @@ impl ClientBuilder {
})
}

/// Add a custom root certificate.
///
/// This can be used to connect to a server that has a self-signed
/// certificate for example.
/// TODO
#[cfg(feature = "default-tls")]
pub fn add_root_certificate(mut self, cert: Certificate) -> ClientBuilder {
self.config.tls.add_root_certificate(cert.cert());
pub fn ues_default_tls(mut self, tls: TlsConnectorBuilder) -> ClientBuilder {
self.config.tls = Some(TlsBackend::Default(tls));
self
}

/// TODO
#[cfg(feature = "rustls-tls")]
pub fn ues_rustls_tls(mut self, tls: rustls::ClientConfig) -> ClientBuilder {
self.config.tls = Some(TlsBackend::Rustls(tls));
self
}

/// Add a custom root certificate.
///
/// This can be used to connect to a server that has a self-signed
/// certificate for example.
#[cfg(feature = "rustls-tls")]
#[cfg(feature = "tls")]
pub fn add_root_certificate(mut self, cert: Certificate) -> ClientBuilder {
// ignore the Result because we have checked it.
let _ = self.config.tls.root_store.add(&cert.cert());
self.config.root_certs.push(cert);
self
}

/// Sets the identity to be used for client certificate authentication.
#[cfg(feature = "default-tls")]
pub fn identity(mut self, identity: Identity) -> ClientBuilder {
self.config.tls.identity(identity.pkcs12());
self
}

/// Sets the identity to be used for client certificate authentication.
#[cfg(feature = "rustls-tls")]
#[cfg(feature = "tls")]
pub fn identity(mut self, identity: Identity) -> ClientBuilder {
let (sk, pk) = identity.into_inner();
self.config.tls.set_single_client_cert(pk, sk);
self.config.identity.push(identity);
self
}

Expand Down
Loading

0 comments on commit 2d1c4c7

Please sign in to comment.