Skip to content

Commit

Permalink
Fix "bad request" without proxy_url
Browse files Browse the repository at this point in the history
  • Loading branch information
kazk committed Feb 26, 2021
1 parent 3ca625b commit 2cd876c
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 43 deletions.
5 changes: 3 additions & 2 deletions kube/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ jsonpatch = ["json-patch"]
ws = ["tokio-tungstenite"]
oauth = ["tame-oauth"]
gzip = ["async-compression"]
proxy-native-tls = ["native-tls", "hyper-proxy/tls"]
proxy-rustls-tls = ["rustls-tls", "hyper-proxy/rustls-base"]
proxy = []
proxy-native-tls = ["native-tls", "proxy", "hyper-proxy/tls"]
proxy-rustls-tls = ["rustls-tls", "proxy", "hyper-proxy/rustls-base"]

[package.metadata.docs.rs]
features = ["derive", "ws", "oauth", "jsonpatch"]
Expand Down
6 changes: 1 addition & 5 deletions kube/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ pub struct Config {
pub(crate) identity: Option<(Vec<u8>, String)>,
/// Stores information to tell the cluster who you are.
pub(crate) auth_info: AuthInfo,
/// Proxy URL
#[cfg(any(feature = "proxy-native-tls", feature = "proxy-rustls-tls"))]
/// Proxy URL. Not used unless `proxy` and `proxy-native-tls`/`proxy-rustls-tls` features are enabled.
pub proxy_url: Option<String>,
}

Expand All @@ -61,7 +60,6 @@ impl Config {
accept_invalid_certs: false,
identity: None,
auth_info: AuthInfo::default(),
#[cfg(any(feature = "proxy-native-tls", feature = "proxy-rustls-tls"))]
proxy_url: None,
}
}
Expand Down Expand Up @@ -124,7 +122,6 @@ impl Config {
token: Some(token),
..Default::default()
},
#[cfg(any(feature = "proxy-native-tls", feature = "proxy-rustls-tls"))]
proxy_url: None,
})
}
Expand Down Expand Up @@ -189,7 +186,6 @@ impl Config {
accept_invalid_certs,
identity: identity_pem.map(|i| (i, String::from(IDENTITY_PASSWORD))),
auth_info: loader.user,
#[cfg(any(feature = "proxy-native-tls", feature = "proxy-rustls-tls"))]
proxy_url: loader.cluster.proxy_url,
})
}
Expand Down
77 changes: 46 additions & 31 deletions kube/src/service/connector.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,46 @@
#[cfg(not(any(feature = "proxy-native-tls", feature = "proxy-rustls-tls")))]
pub use inner::https_connector;
#[cfg(any(feature = "proxy-native-tls", feature = "proxy-rustls-tls"))]
pub use inner::proxy_connector;
#[cfg(feature = "proxy")] pub use inner::proxy_connector;

#[cfg(feature = "rustls-tls")] pub use inner::tls_config;
#[cfg(feature = "native-tls")] pub use inner::tls_connector;

#[cfg(feature = "native-tls")]
mod inner {
use std::convert::{TryFrom, TryInto};

use hyper::client::HttpConnector;
use tokio_native_tls::native_tls::{self, Certificate, Identity};
use hyper_tls::HttpsConnector;
use tokio_native_tls::{
native_tls::{self, Certificate, Identity},
TlsConnector as AsyncTlsConnector,
};

#[cfg(feature = "proxy-native-tls")]
use hyper_proxy::{Intercept, Proxy, ProxyConnector};

use crate::{Config, Error, Result};

#[cfg(not(feature = "proxy-native-tls"))]
pub fn https_connector(config: Config) -> Result<hyper_tls::HttpsConnector<HttpConnector>> {
pub fn tls_connector(config: Config) -> Result<native_tls::TlsConnector> {
config.try_into()
}

pub fn https_connector(connector: native_tls::TlsConnector) -> HttpsConnector<HttpConnector> {
let mut http = HttpConnector::new();
http.enforce_http(false);
let connector: native_tls::TlsConnector = config.try_into()?;
let tls = tokio_native_tls::TlsConnector::from(connector);
Ok(hyper_tls::HttpsConnector::from((http, tls)))
HttpsConnector::from((http, AsyncTlsConnector::from(connector)))
}

#[cfg(feature = "proxy-native-tls")]
pub fn proxy_connector(config: Config) -> Result<hyper_proxy::ProxyConnector<HttpConnector>> {
use hyper_proxy::{Intercept, Proxy, ProxyConnector};
let mut http = HttpConnector::new();
http.enforce_http(false);
let mut connector = ProxyConnector::unsecured(http);
if let Some(proxy_url) = &config.proxy_url {
connector.add_proxy(Proxy::new(Intercept::All, proxy_url.parse()?));
pub fn proxy_connector(
connector: native_tls::TlsConnector,
proxy_url: Option<http::uri::Uri>,
) -> hyper_proxy::ProxyConnector<HttpsConnector<HttpConnector>> {
let mut proxy = ProxyConnector::unsecured(https_connector(connector.clone()));
if let Some(proxy_url) = proxy_url {
proxy.add_proxy(Proxy::new(Intercept::All, proxy_url));
}
connector.set_tls(Some(config.try_into()?));
Ok(connector)
proxy.set_tls(Some(connector));
proxy
}

impl TryFrom<Config> for native_tls::TlsConnector {
Expand Down Expand Up @@ -81,33 +90,39 @@ mod inner {
};

use hyper::client::HttpConnector;
use hyper_rustls::HttpsConnector;
use tokio_rustls::{
rustls::{self, Certificate, ClientConfig, ServerCertVerified, ServerCertVerifier},
webpki::DNSNameRef,
};

#[cfg(feature = "proxy-rustls-tls")]
use hyper_proxy::{Intercept, Proxy, ProxyConnector};

use crate::{config::Config, Error, Result};

#[cfg(not(feature = "proxy-rustls-tls"))]
pub fn https_connector(config: Config) -> Result<hyper_rustls::HttpsConnector<HttpConnector>> {
pub fn tls_config(config: Config) -> Result<Arc<ClientConfig>> {
Ok(Arc::new(config.try_into()?))
}

pub fn https_connector(tls_config: Arc<ClientConfig>) -> HttpsConnector<HttpConnector> {
let mut http = HttpConnector::new();
http.enforce_http(false);
let client_config = Arc::new(config.try_into()?);
Ok(hyper_rustls::HttpsConnector::from((http, client_config)))
HttpsConnector::from((http, tls_config))
}

#[cfg(feature = "proxy-rustls-tls")]
pub fn proxy_connector(config: Config) -> Result<hyper_proxy::ProxyConnector<HttpConnector>> {
use hyper_proxy::{Intercept, Proxy, ProxyConnector};
let mut http = HttpConnector::new();
http.enforce_http(false);
let mut connector = ProxyConnector::unsecured(http);
if let Some(proxy_url) = &config.proxy_url {
connector.add_proxy(Proxy::new(Intercept::All, proxy_url.parse()?));
pub fn proxy_connector(
tls_config: Arc<ClientConfig>,
proxy_url: Option<http::uri::Uri>,
) -> hyper_proxy::ProxyConnector<HttpsConnector<HttpConnector>> {
let mut connector = ProxyConnector::unsecured(https_connector(tls_config.clone()));
if let Some(proxy_url) = proxy_url {
connector.add_proxy(Proxy::new(Intercept::All, proxy_url));
}
let tls = tokio_rustls::TlsConnector::from(Arc::new(config.try_into()?));
let tls = tokio_rustls::TlsConnector::from(tls_config);
connector.set_tls(Some(tls));
Ok(connector)
connector
}

impl TryFrom<Config> for ClientConfig {
Expand Down
20 changes: 15 additions & 5 deletions kube/src/service/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,21 @@ impl TryFrom<Config> for Service {
connector
});

// Proxy connector with TLS or Https connector
#[cfg(any(feature = "proxy-native-tls", feature = "proxy-rustls-tls"))]
let conn = connector::proxy_connector(config)?;
#[cfg(not(any(feature = "proxy-native-tls", feature = "proxy-rustls-tls")))]
let conn = connector::https_connector(config)?;
let proxy_url = if let Some(url) = &config.proxy_url {
Some(url.parse::<http::uri::Uri>()?)
} else {
None
};
// TODO Pass only required fields from `Config`
#[cfg(feature = "native-tls")]
let tls = connector::tls_connector(config)?;
#[cfg(feature = "rustls-tls")]
let tls = connector::tls_config(config)?;

#[cfg(not(feature = "proxy"))]
let conn = connector::https_connector(tls);
#[cfg(feature = "proxy")]
let conn = connector::proxy_connector(tls, proxy_url);

let conn = ServiceBuilder::new().layer(with_timeout).service(conn);
let client: HyperClient<_, Body> = HyperClient::builder().build(conn);
Expand Down

0 comments on commit 2cd876c

Please sign in to comment.