Skip to content

fix(fetch)!: stop the tokio feature from selecting a rustls crypto provider - #616

Draft
Vaiz wants to merge 1 commit into
mainfrom
fetch-tokio-no-aws-lc
Draft

fix(fetch)!: stop the tokio feature from selecting a rustls crypto provider#616
Vaiz wants to merge 1 commit into
mainfrom
fetch-tokio-no-aws-lc

Conversation

@Vaiz

@Vaiz Vaiz commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

fetch's tokio feature enabled rustls?/aws-lc-rs. tokio is a runtime/transport selector and must not choose a TLS crypto provider.

Because rustls?/... is a weak dependency feature it looks inert in isolation, but as soon as anything else in the same workspace enables dep:rustls (for example via fetch/rustls), Cargo's workspace-wide feature unification activates it and forces rustls onto aws-lc-rs, dragging in aws-lc-rs + aws-lc-sys and its native NASM/C build.

This bit a real consumer: crates selecting only
fetch = { features = ["tokio", "native-tls"] } still ended up with aws-lc-rs/aws-lc-sys in Cargo.lock in a workspace that deliberately drives rustls with default-features = false plus a different provider. Dropping "tokio" from those manifests made aws-lc-rs disappear, confirming fetch/tokio was the trigger.

Changes:

  • tokio no longer implies any crypto provider.
  • New opt-in rustls-aws-lc-rs feature carries rustls/aws-lc-rs.
  • tls is now rustls + rustls-aws-lc-rs, so it keeps its documented "rustls with aws-lc-rs" meaning and stays the recommended way to turn on HTTPS.
  • rustls alone is provider-neutral: the Tokio transport resolves the process-wide default installed via CryptoProvider::install_default, and panics with an actionable message when none is installed.
  • Examples/tests that actually negotiate TLS now require tls instead of rustls, as does fetch_azure's dev-dependency on fetch.
  • Crate docs/README describe the provider choice and the new feature.

Verified with cargo tree -e normal -i aws-lc-rs: fetch with tokio,rustls no longer pulls aws-lc-rs, while tokio,rustls,rustls-aws-lc-rs (and tokio,tls) still does.

BREAKING CHANGE: fetch/tokio no longer implies the aws-lc-rs rustls crypto provider. Users who relied on features = ["tokio", "rustls"] giving them a working provider must switch to features = ["tokio", "tls"] (or add rustls-aws-lc-rs), or install a provider themselves with rustls::crypto::CryptoProvider::install_default.

…provider

`fetch`'s `tokio` feature enabled `rustls?/aws-lc-rs`. `tokio` is a
runtime/transport selector and must not choose a TLS crypto provider.

Because `rustls?/...` is a weak dependency feature it looks inert in
isolation, but as soon as anything else in the same workspace enables
`dep:rustls` (for example via `fetch/rustls`), Cargo's workspace-wide
feature unification activates it and forces rustls onto aws-lc-rs,
dragging in `aws-lc-rs` + `aws-lc-sys` and its native NASM/C build.

This bit a real consumer: crates selecting only
`fetch = { features = ["tokio", "native-tls"] }` still ended up with
`aws-lc-rs`/`aws-lc-sys` in `Cargo.lock` in a workspace that
deliberately drives rustls with `default-features = false` plus a
different provider. Dropping `"tokio"` from those manifests made
aws-lc-rs disappear, confirming `fetch/tokio` was the trigger.

Changes:

- `tokio` no longer implies any crypto provider.
- New opt-in `rustls-aws-lc-rs` feature carries `rustls/aws-lc-rs`.
- `tls` is now `rustls` + `rustls-aws-lc-rs`, so it keeps its documented
  "rustls with aws-lc-rs" meaning and stays the recommended way to turn
  on HTTPS.
- `rustls` alone is provider-neutral: the Tokio transport resolves the
  process-wide default installed via `CryptoProvider::install_default`,
  and panics with an actionable message when none is installed.
- Examples/tests that actually negotiate TLS now require `tls` instead of
  `rustls`, as does `fetch_azure`'s dev-dependency on `fetch`.
- Crate docs/README describe the provider choice and the new feature.

Verified with `cargo tree -e normal -i aws-lc-rs`: `fetch` with
`tokio,rustls` no longer pulls aws-lc-rs, while `tokio,rustls,rustls-aws-lc-rs`
(and `tokio,tls`) still does.

BREAKING CHANGE: `fetch/tokio` no longer implies the `aws-lc-rs` rustls
crypto provider. Users who relied on `features = ["tokio", "rustls"]`
giving them a working provider must switch to `features = ["tokio", "tls"]`
(or add `rustls-aws-lc-rs`), or install a provider themselves with
`rustls::crypto::CryptoProvider::install_default`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 29, 2026 16:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors fetch’s feature model so runtime/transport selection (tokio) no longer implicitly selects a rustls crypto provider, avoiding workspace feature unification pulling in aws-lc-rs/aws-lc-sys unexpectedly. It introduces an explicit opt-in feature for the aws-lc-rs provider, updates the Tokio transport to use either that opt-in provider or a process-wide default, and aligns docs/examples/tests with the new behavior.

Changes:

  • Remove the implicit rustls/aws-lc-rs selection from fetch/tokio; add rustls-aws-lc-rs and redefine tls as rustls + rustls-aws-lc-rs.
  • Update Tokio rustls wiring to use the provider from rustls-aws-lc-rs or the process-wide default (with an actionable panic if none is installed).
  • Update crate docs/README and example/test required-features (and fetch_azure dev-dependency) to use tls where TLS negotiation is required.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
crates/fetch/src/tokio.rs Switch rustls crypto provider selection to feature/process-default and update related docs/messages.
crates/fetch/src/lib.rs Update crate-level documentation to explain provider selection and new features.
crates/fetch/README.md Regenerated README reflecting the new provider feature model and guidance.
crates/fetch/Cargo.toml Introduce rustls-aws-lc-rs, redefine tls, and adjust examples/tests to require tls.
crates/fetch_azure/Cargo.toml Update dev-dependency on fetch to use tls for TLS-negotiating tests/examples.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/fetch/src/tokio.rs
Comment on lines +168 to +170
/// Returns the aws-lc-rs crypto provider selected by the `rustls-aws-lc-rs` feature.
#[cfg(any(feature = "rustls-aws-lc-rs", test))]
fn rustls_crypto_provider() -> std::sync::Arc<::rustls::crypto::CryptoProvider> {
Comment thread crates/fetch/src/tokio.rs
Comment on lines +182 to +185
::rustls::crypto::CryptoProvider::get_default().cloned().expect(
"no rustls crypto provider is installed: enable the `rustls-aws-lc-rs` (or `tls`) feature of `fetch`, \
or call `rustls::crypto::CryptoProvider::install_default` before creating the client",
)
Comment thread crates/fetch/src/tokio.rs
Comment on lines +180 to +186
#[cfg(all(feature = "rustls", not(any(feature = "rustls-aws-lc-rs", test))))]
fn rustls_crypto_provider() -> std::sync::Arc<::rustls::crypto::CryptoProvider> {
::rustls::crypto::CryptoProvider::get_default().cloned().expect(
"no rustls crypto provider is installed: enable the `rustls-aws-lc-rs` (or `tls`) feature of `fetch`, \
or call `rustls::crypto::CryptoProvider::install_default` before creating the client",
)
}
@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.0%. Comparing base (3de0039) to head (0ad12d0).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #616   +/-   ##
=======================================
  Coverage   100.0%   100.0%           
=======================================
  Files         443      443           
  Lines       43455    43457    +2     
=======================================
+ Hits        43455    43457    +2     
Flag Coverage Δ
linux 60.8% <100.0%> (?)
linux-arm 62.2% <100.0%> (?)
windows 62.6% <100.0%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@martintmk

Copy link
Copy Markdown
Member

One downgraded scenario of this change would be customer that explicitly constructs TlsOptions, provides his own override for crypto provider and then when constructing fetch it fails with static provider not being installed.

https://docs.rs/fetch_tls/latest/fetch_tls/struct.TlsBackendBuilder.html#method.configure_rustls.

I would change fetch_tls::TlsBackendBuilder::configure_rustls to accept in Option<Arc<CryptoProvider>> rather than Arc<CryptoProvider>. This way when consumer overrides crypto provider , TlsBackendBuilder doesn't need to access installed provider to crate TlsBackend and will just use one provided by the consumer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants