From 4a59f1e21912f13213756016c5c5a78f88d75233 Mon Sep 17 00:00:00 2001 From: Jeremiah Senkpiel Date: Fri, 15 Mar 2024 15:01:06 -0700 Subject: [PATCH] feat: builder with shared configuration Sometimes one might want to share the config to the builder api like one can to the connector api itself, allowing some optimization. Since the config eventually get's `Arc`-d anyways there can be no disadvantage to this. --- .vscode/settings.json | 3 +++ src/connector/builder.rs | 27 +++++++++++++++++---------- 2 files changed, 20 insertions(+), 10 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..39a5ca1 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "rust-analyzer.cargo.features": "all" +} diff --git a/src/connector/builder.rs b/src/connector/builder.rs index 3e1abda..360d490 100644 --- a/src/connector/builder.rs +++ b/src/connector/builder.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use hyper_util::client::legacy::connect::HttpConnector; #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] use rustls::crypto::CryptoProvider; @@ -35,7 +37,7 @@ impl ConnectorBuilder { Self(WantsTlsConfig(())) } - /// Passes a rustls [`ClientConfig`] to configure the TLS connection + /// Passes a rustls [`ClientConfig`] to configure the TLS connection. /// /// The [`alpn_protocols`](ClientConfig::alpn_protocols) field is /// required to be empty (or the function will panic) and will be @@ -43,12 +45,16 @@ impl ConnectorBuilder { /// [`enable_http1`](ConnectorBuilder::enable_http1), /// [`enable_http2`](ConnectorBuilder::enable_http2)) before the /// connector is built. - pub fn with_tls_config(self, config: ClientConfig) -> ConnectorBuilder { + pub fn with_tls_config( + self, + config: impl Into>, + ) -> ConnectorBuilder { + let tls_config = config.into(); assert!( - config.alpn_protocols.is_empty(), + tls_config.alpn_protocols.is_empty(), "ALPN protocols should not be pre-defined" ); - ConnectorBuilder(WantsSchemes { tls_config: config }) + ConnectorBuilder(WantsSchemes { tls_config }) } /// Use rustls' default crypto provider and other defaults, and the platform verifier @@ -133,7 +139,7 @@ impl Default for ConnectorBuilder { /// State of a builder that needs schemes (https:// and http://) to be /// configured next pub struct WantsSchemes { - tls_config: ClientConfig, + tls_config: Arc, } impl ConnectorBuilder { @@ -166,7 +172,7 @@ impl ConnectorBuilder { /// /// No protocol has been enabled at this point. pub struct WantsProtocols1 { - tls_config: ClientConfig, + tls_config: Arc, https_only: bool, override_server_name: Option, } @@ -176,7 +182,7 @@ impl WantsProtocols1 { HttpsConnector { force_https: self.https_only, http: conn, - tls_config: std::sync::Arc::new(self.tls_config), + tls_config: self.tls_config, override_server_name: self.override_server_name, } } @@ -203,7 +209,7 @@ impl ConnectorBuilder { /// This needs to be called explicitly, no protocol is enabled by default #[cfg(feature = "http2")] pub fn enable_http2(mut self) -> ConnectorBuilder { - self.0.tls_config.alpn_protocols = vec![b"h2".to_vec()]; + Arc::make_mut(&mut self.0.tls_config).alpn_protocols = vec![b"h2".to_vec()]; ConnectorBuilder(WantsProtocols3 { inner: self.0, enable_http1: false, @@ -221,7 +227,7 @@ impl ConnectorBuilder { #[cfg(not(feature = "http1"))] let alpn_protocols = vec![b"h2".to_vec()]; - self.0.tls_config.alpn_protocols = alpn_protocols; + Arc::make_mut(&mut self.0.tls_config).alpn_protocols = alpn_protocols; ConnectorBuilder(WantsProtocols3 { inner: self.0, enable_http1: cfg!(feature = "http1"), @@ -259,7 +265,8 @@ impl ConnectorBuilder { /// This needs to be called explicitly, no protocol is enabled by default #[cfg(feature = "http2")] pub fn enable_http2(mut self) -> ConnectorBuilder { - self.0.inner.tls_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; + Arc::make_mut(&mut self.0.inner.tls_config).alpn_protocols = + vec![b"h2".to_vec(), b"http/1.1".to_vec()]; ConnectorBuilder(WantsProtocols3 { inner: self.0.inner, enable_http1: true,