From a30ba984f5e7d02cc9d639654fdf875ac3e3e53a Mon Sep 17 00:00:00 2001 From: Markus Probst Date: Sun, 1 Jun 2025 14:12:01 +0200 Subject: [PATCH 1/2] Allow the server_name_resolver to be overriden --- src/async_impl/client.rs | 16 ++++++++++++++++ src/connect.rs | 15 ++++++++------- src/lib.rs | 4 ++++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/async_impl/client.rs b/src/async_impl/client.rs index c79546385..879f8f8a9 100644 --- a/src/async_impl/client.rs +++ b/src/async_impl/client.rs @@ -185,6 +185,8 @@ struct Config { tls_built_in_certs_native: bool, #[cfg(feature = "__rustls")] crls: Vec, + #[cfg(feature = "__rustls")] + server_name_resolver: Arc, #[cfg(feature = "__tls")] min_tls_version: Option, #[cfg(feature = "__tls")] @@ -308,6 +310,8 @@ impl ClientBuilder { identity: None, #[cfg(feature = "__rustls")] crls: vec![], + #[cfg(feature = "__rustls")] + server_name_resolver: Arc::new(hyper_rustls::DefaultServerNameResolver::default()), #[cfg(feature = "__tls")] min_tls_version: None, #[cfg(feature = "__tls")] @@ -657,6 +661,7 @@ impl ClientBuilder { config.interface.as_deref(), config.nodelay, config.tls_info, + config.server_name_resolver, ) } #[cfg(feature = "__rustls")] @@ -862,6 +867,7 @@ impl ClientBuilder { config.interface.as_deref(), config.nodelay, config.tls_info, + config.server_name_resolver, ) } #[cfg(any(feature = "native-tls", feature = "__rustls",))] @@ -1691,6 +1697,16 @@ impl ClientBuilder { self } + /// Sets the server name resolver. Defaults to `hyper_rustls::DefaultServerNameResolver` + /// + /// This requires the `rustls-tls(-...)` Cargo feature enabled. + #[cfg(feature = "__rustls")] + #[cfg_attr(docsrs, doc(cfg(feature = "rustls-tls")))] + pub fn with_server_name_resolver(mut self, server_name_resolver: Arc) -> ClientBuilder { + self.config.server_name_resolver = server_name_resolver; + self + } + // TLS options /// Add a custom root certificate. diff --git a/src/connect.rs b/src/connect.rs index 820244e95..7e21ce04f 100644 --- a/src/connect.rs +++ b/src/connect.rs @@ -330,6 +330,7 @@ where { interface: Option<&str>, nodelay: bool, tls_info: bool, + server_name_resolver: Arc, ) -> ConnectorBuilder where T: Into>, @@ -367,6 +368,7 @@ where { http, tls, tls_proxy, + server_name_resolver, }, proxies, verbose: verbose::OFF, @@ -458,6 +460,7 @@ enum Inner { http: HttpConnector, tls: Arc, tls_proxy: Arc, + server_name_resolver: Arc, }, } @@ -579,7 +582,7 @@ impl ConnectorService { } } #[cfg(feature = "__rustls")] - Inner::RustlsTls { http, tls, .. } => { + Inner::RustlsTls { http, tls, server_name_resolver, .. } => { let mut http = http.clone(); // Disable Nagle's algorithm for TLS handshake @@ -589,7 +592,7 @@ impl ConnectorService { http.set_nodelay(true); } - let mut http = hyper_rustls::HttpsConnector::from((http, tls.clone())); + let mut http = hyper_rustls::HttpsConnector::new(http, tls.clone(), false, server_name_resolver); let io = http.call(dst).await?; if let hyper_rustls::MaybeHttpsStream::Https(stream) = io { @@ -675,10 +678,9 @@ impl ConnectorService { http, tls, tls_proxy, + server_name_resolver: name_resolver, } => { if dst.scheme() == Some(&Scheme::HTTPS) { - use rustls_pki_types::ServerName; - use std::convert::TryFrom; use tokio_rustls::TlsConnector as RustlsConnector; log::trace!("tunneling HTTPS over proxy"); @@ -701,9 +703,8 @@ impl ConnectorService { // We don't wrap this again in an HttpsConnector since that uses Maybe, // and we know this is definitely HTTPS. let tunneled = tunnel.call(dst.clone()).await?; - let host = dst.host().ok_or("no host in url")?.to_string(); - let server_name = ServerName::try_from(host.as_str().to_owned()) - .map_err(|_| "Invalid Server Name")?; + + let server_name = name_resolver.resolve(&dst)?; let io = RustlsConnector::from(tls.clone()) .connect(server_name, TokioIo::new(tunneled)) .await?; diff --git a/src/lib.rs b/src/lib.rs index 23b8ad0c2..f73f22b89 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -287,6 +287,10 @@ pub use self::error::{Error, Result}; pub use self::into_url::IntoUrl; pub use self::response::ResponseBuilderExt; +#[cfg(feature = "__rustls")] +#[cfg_attr(docsrs, doc(cfg(feature = "rustls-tls")))] +pub use hyper_rustls::ResolveServerName; + /// Shortcut method to quickly make a `GET` request. /// /// See also the methods on the [`reqwest::Response`](./struct.Response.html) From 00eeede41a4cf24bdbfc437707b40e661c891569 Mon Sep 17 00:00:00 2001 From: Markus Probst Date: Sat, 30 Aug 2025 16:28:39 +0200 Subject: [PATCH 2/2] Use upstream git remote --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 3f574e6e4..003aaac36 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -141,7 +141,7 @@ native-tls-crate = { version = "0.2.10", optional = true, package = "native-tls" tokio-native-tls = { version = "0.3.0", optional = true } # rustls-tls -hyper-rustls = { version = "0.27.0", default-features = false, optional = true, features = ["http1", "tls12"] } +hyper-rustls = { git = "https://github.com/rustls/hyper-rustls.git", rev = "5e9b69b4128abfc147e8b6fa55977eac4c3f575c", default-features = false, optional = true, features = ["http1", "tls12"] } rustls = { version = "0.23.4", optional = true, default-features = false, features = ["std", "tls12"] } tokio-rustls = { version = "0.26", optional = true, default-features = false, features = ["tls12"] } webpki-roots = { version = "1", optional = true }