diff --git a/src/connector.rs b/src/connector.rs index 76dbf52..afe48ff 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -18,6 +18,7 @@ type BoxError = Box; /// A Connector for the `https` scheme. #[derive(Clone)] pub struct HttpsConnector { + force_https: bool, http: T, tls_config: Arc, } @@ -57,6 +58,13 @@ impl HttpsConnector { Self::build(config) } + /// Force the use of HTTPS when connecting. + /// + /// If a URL is not `https` when connecting, an error is returned. Disabled by default. + pub fn https_only(&mut self, enable: bool) { + self.force_https = enable; + } + fn build(mut config: ClientConfig) -> Self { let mut http = HttpConnector::new(); http.enforce_http(false); @@ -69,7 +77,9 @@ impl HttpsConnector { impl fmt::Debug for HttpsConnector { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("HttpsConnector").finish() + f.debug_struct("HttpsConnector") + .field("force_https", &self.force_https) + .finish() } } @@ -79,6 +89,7 @@ where { fn from((http, cfg): (H, C)) -> Self { HttpsConnector { + force_https: false, http, tls_config: cfg.into(), } @@ -110,7 +121,11 @@ where fn call(&mut self, dst: Uri) -> Self::Future { let is_https = dst.scheme_str() == Some("https"); - if !is_https { + if !is_https && self.force_https { + // Early abort if HTTPS is forced but can't be used + let err = io::Error::new(io::ErrorKind::Other, "https required but URI was not https"); + Box::pin(async move { Err(err.into()) }) + } else if !is_https { let connecting_future = self.http.call(dst); let f = async move {