Repository navigation
perf(pm): probe — rustls aws-lc-rs alone #2835
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -93,6 +93,49 @@ pub(crate) fn get_client() -> Result<&'static reqwest::Client> { | |
| HTTP_CLIENT.as_ref().map_err(|e| anyhow!("{e}")) | ||
| } | ||
|
|
||
| /// Build a `rustls::ClientConfig` using the `aws-lc-rs` crypto provider | ||
| /// instead of reqwest's default `ring`. Measured on CI (4-core runner) | ||
| /// against npmjs.org, ring's per-TLS-handshake client-side CPU cost | ||
| /// (ECDHE key derivation + cert verification + Finished MAC) serialised | ||
| /// across 128 parallel handshakes into a 154 ms "CCS → first AppData" | ||
| /// span — the HTTP requests couldn't fire until all TLS crypto drained | ||
| /// through 4 async workers. aws-lc-rs uses BoringSSL's assembly-optimised | ||
| /// primitives and is roughly 3× faster at handshake work. | ||
| #[cfg(not(target_arch = "wasm32"))] | ||
| fn build_rustls_config() -> Result<rustls::ClientConfig> { | ||
| // Install aws-lc-rs as the default for any other rustls consumer in | ||
| // the process. Idempotent — only the first call per process wins. | ||
| let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); | ||
|
|
||
| // Load OS root certs. On Linux this hits /etc/ssl/certs/, | ||
| // on macOS it queries the Security framework keychain. Called once | ||
| // per process via `HTTP_CLIENT`'s `LazyLock`. | ||
| let roots = rustls_native_certs::load_native_certs(); | ||
| let mut root_store = rustls::RootCertStore::empty(); | ||
| for cert in roots.certs { | ||
| // Best-effort: skip any cert rustls refuses (same tolerance | ||
| // native-tls shows). A hard fail here would brick every | ||
| // request on a box with one bad root in its trust store. | ||
| let _ = root_store.add(cert); | ||
| } | ||
|
Comment on lines
+115
to
+120
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If |
||
| if !roots.errors.is_empty() { | ||
| tracing::debug!( | ||
| "rustls-native-certs reported {} non-fatal load issues", | ||
| roots.errors.len() | ||
| ); | ||
| } | ||
|
|
||
| let config = rustls::ClientConfig::builder_with_provider(std::sync::Arc::new( | ||
| rustls::crypto::aws_lc_rs::default_provider(), | ||
| )) | ||
| .with_safe_default_protocol_versions() | ||
| .map_err(|e| anyhow!("rustls safe_default_protocol_versions: {e}"))? | ||
| .with_root_certificates(root_store) | ||
| .with_no_client_auth(); | ||
|
|
||
| Ok(config) | ||
| } | ||
|
|
||
| /// Create a [`reqwest::ClientBuilder`] with TLS, DNS caching, and proxy | ||
| /// from environment variables. | ||
| /// | ||
|
|
@@ -112,8 +155,9 @@ pub fn client_builder() -> Result<reqwest::ClientBuilder> { | |
| let builder = { | ||
| use crate::service::dns::shared_resolver; | ||
|
|
||
| let tls_config = build_rustls_config()?; | ||
| let mut builder = builder | ||
| .use_rustls_tls() | ||
| .use_preconfigured_tls(tls_config) | ||
| .no_proxy() | ||
| .dns_resolver(shared_resolver()); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Calling
install_default()sets the process-wide default crypto provider forrustls. While this is generally acceptable for a CLI tool, it can cause conflicts if this crate is ever used as a library within a larger application that has already initialized a different provider (likering). Since you are already explicitly passing the provider viabuilder_with_provideron line 128, this global installation might be unnecessary unless you intend to affect otherrustlsconsumers in the same process.