Skip to content

Allow overriding the reqwest TLS backend - #327

Open
s-panferov wants to merge 1 commit into
ayrat555:masterfrom
s-panferov:allow-overriding-reqwest-tls
Open

Allow overriding the reqwest TLS backend#327
s-panferov wants to merge 1 commit into
ayrat555:masterfrom
s-panferov:allow-overriding-reqwest-tls

Conversation

@s-panferov

Copy link
Copy Markdown

Problem

The client-reqwest feature pulls in reqwest with a hardcoded rustls feature:

[target.'cfg(not(target_arch = "wasm32"))'.dependencies.reqwest]
features = ["multipart", "stream", "rustls"]

reqwest's rustls feature selects the aws-lc-rs crypto provider, which builds the aws-lc-sys crate via a slow C/CMake build script. Because Cargo features are additive, a downstream cannot opt out of aws-lc-rs once client-reqwest is enabled — even if they configure reqwest elsewhere with rustls-no-provider or native-tls, the rustls (aws-lc-rs) feature still wins.

Change

Move the TLS backend selection into frankenstein's own features and stop hardcoding it on the reqwest dependency:

  • rustls-tls — rustls with the aws-lc-rs provider. Enabled by default, so existing users keep the previous behaviour.
  • rustls-tls-no-provider — rustls without a built-in crypto provider (install your own, e.g. rustls::crypto::ring::default_provider().install_default()); avoids aws-lc-sys.
  • native-tls — the platform's native TLS.

Each maps to the corresponding reqwest feature with the weak-dependency syntax (reqwest?/...), so they are no-ops unless the reqwest client is enabled.

Backwards compatibility

  • Users who keep default features (e.g. features = ["client-reqwest"]) are unaffecteddefault = ["rustls-tls"] reproduces the old rustls/aws-lc-rs setup.

  • Users who already pass default-features = false and want a lighter provider can now do:

    frankenstein = { version = "0.50", default-features = false, features = ["client-reqwest", "rustls-tls-no-provider"] }

Verification

  • cargo check --features client-reqwest (default) — still resolves aws-lc-rs.
  • cargo check --no-default-features --features client-reqwest,rustls-tls-no-providerno aws-lc-rs/aws-lc-sys in the tree.
  • cargo check --no-default-features --features client-ureq and cargo check --all-features both build.

@EdJoPaTo EdJoPaTo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Hey there! Thank you for your PR and bringing up this issue!

I am not entirely happy with this, but this is mainly due to the fact that I would prefer frankenstein to be only a thin wrapper around external clients like reqwest and not much more. But I think that's hard to reach due to the trait requirements of Rust… So nothing to blame you 😇

Comment thread CHANGELOG.md Outdated
Comment thread Cargo.toml Outdated
all-features = true

[features]
default = ["rustls-tls"]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Just as an idea, if it doesn't work out well I'm also happy about it.

What if it would be default = ["reqwest?/rustls"] and no rustls related features? When someone wants the default rustls it still works fine. If someone wants something else, no-default-features and rustls as a dependency in your crate and define it yourself with all the options rustls provides.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Let me see, but I don't think it works

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I'm building a test crate to make sure it actually works

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I've updated the code with your design

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think its more clean that way. But I think now we need to adapt the feature toggle for the default feature, rather than on the reqwest feature for wasm32:

target.'cfg(not(target_arch = "wasm32"))'.dependencies.reqwest

@s-panferov

Copy link
Copy Markdown
Author

@EdJoPaTo if you see how other popular request-dependent crates do, almost all of them have to expose this complexity :-( Different environments have different requirements and TLS backend is something people want to tweak pretty often.

@ayrat555

ayrat555 commented Jul 3, 2026

Copy link
Copy Markdown
Owner

@EdJoPaTo do you think it's good to merge?

rustls with the aws-lc-rs provider stays the default (via the default
feature => reqwest?/rustls). To use a different backend, disable default
features and add your own reqwest dependency selecting the TLS features
you want; previously the rustls/aws-lc-rs provider was hardcoded and
impossible to opt out of because Cargo features are additive.
@s-panferov
s-panferov force-pushed the allow-overriding-reqwest-tls branch from baf844b to c2682f7 Compare July 4, 2026 20:06
@EdJoPaTo

Copy link
Copy Markdown
Collaborator

Sorry for taking so long to answer currently 😔

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