-
Notifications
You must be signed in to change notification settings - Fork 784
feat(http-transport-reqwest): allow tls options #7798
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
Merged
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
6c8970a
feat(http-transport-reqwest): allow tls options
erickguan dede66d
Update reqwest feature
erickguan 2676e10
fix reqwest tls backend configuration
erickguan 0a3522a
fix reqwest rustls webpki feature name
erickguan 2de79e8
add reqwest rustls ring backend
erickguan 57f4c67
clarify reqwest tls backend default
erickguan 76cc17d
Update comment
erickguan 1d887a0
simplify reqwest tls backend selection
erickguan fed18c9
Address issues in feature configurations, dependencies
erickguan 4487b59
Set default transport to rustls
erickguan 09d5e0c
Fix compilation error in CI
erickguan dc4aa7e
Remove non TLS backend build
erickguan b84e44e
fix Cargo.toml
erickguan e8dce1c
Bring back default but point to default feature
erickguan ce37d8a
Fix default feature set
erickguan 2f82fc6
Fix default feature
erickguan 1e6d1e8
Simplify reqwest TLS configuration
erickguan eab6d50
Document reqwest webpki roots TLS setup
erickguan 9aee9e8
Prettify comment
erickguan d615f06
Remove opendal_http_transport_reqwest export in core
erickguan c46ac0f
fix linting
erickguan 3eaf192
Remove default builder
erickguan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,196 @@ | ||
| # opendal-http-transport-reqwest | ||
|
|
||
| Reqwest-based HTTP transport for [Apache OpenDAL](https://opendal.apache.org). | ||
|
|
||
| This crate provides `ReqwestTransport`, an implementation of OpenDAL's | ||
| `HttpTransport` trait backed by [reqwest](https://crates.io/crates/reqwest). | ||
|
|
||
| ## TLS configuration | ||
|
|
||
| OpenDAL does not add another TLS backend selector on top of reqwest. Pick the | ||
| Cargo feature set you need, build a `reqwest::Client` with reqwest's | ||
| `ClientBuilder`, and pass that client to `ReqwestTransport::new`. | ||
|
|
||
| The default feature is `rustls`. When `ReqwestTransport::default()` is used on | ||
| native targets, this crate explicitly asks reqwest for the Rustls backend if the | ||
| `rustls` feature is compiled in. | ||
|
|
||
| If this crate is built with only `rustls-no-provider`, install a Rustls default | ||
| crypto provider before using `ReqwestTransport::default()`, or build a | ||
| preconfigured `reqwest::Client` yourself and pass it to `ReqwestTransport::new`. | ||
|
|
||
| ### Reqwest TLS resolution | ||
|
|
||
| Reqwest has its own TLS resolution rules. For OpenDAL users, the practical | ||
| resolution order is: | ||
|
|
||
| - Explicit reqwest client configuration wins. Call | ||
| `ClientBuilder::tls_backend_rustls()`, | ||
| `ClientBuilder::tls_backend_native()`, or | ||
| `ClientBuilder::tls_backend_preconfigured()`, but reqwest documents that API | ||
| as semver-unstable because the concrete TLS config type must match reqwest's | ||
| dependency versions. | ||
| - Otherwise, reqwest's automatic TLS backend selection applies. The reqwest | ||
| `default-tls` feature takes precedence if any crate in the dependency tree | ||
| enables it. Disable reqwest defaults with `default-features = false` when you | ||
| need deterministic TLS features. | ||
| - Cargo features are additive. If multiple TLS backends are compiled by feature | ||
| unification, use explicit client configuration instead of relying on automatic | ||
| selection. | ||
|
|
||
| See reqwest's TLS documentation: | ||
|
|
||
| - [reqwest TLS module](https://docs.rs/reqwest/latest/reqwest/tls/index.html) | ||
| - [ClientBuilder::tls_backend_rustls](https://docs.rs/reqwest/latest/reqwest/struct.ClientBuilder.html#method.tls_backend_rustls) | ||
| - [ClientBuilder::tls_backend_native](https://docs.rs/reqwest/latest/reqwest/struct.ClientBuilder.html#method.tls_backend_native) | ||
| - [ClientBuilder::tls_backend_preconfigured](https://docs.rs/reqwest/latest/reqwest/struct.ClientBuilder.html#method.tls_backend_preconfigured) | ||
|
|
||
| ### Feature matrix | ||
|
Xuanwo marked this conversation as resolved.
|
||
|
|
||
| | Feature | Crypto provider | Certificate roots | Use when | | ||
| |---------|-----------------|-------------------|----------| | ||
| | `rustls` (default) | reqwest default | Platform verifier | Pure-Rust TLS with the system trust store | | ||
| | `rustls-no-provider` | You provide | You provide | BYO crypto provider, roots, or FIPS module | | ||
| | `native-tls` | OS library | OS trust store | You want platform TLS | | ||
|
|
||
| ## Cargo features | ||
|
|
||
| Most users depend on the `opendal` facade crate: | ||
|
|
||
| ```toml | ||
| [dependencies] | ||
| # Default: reqwest transport with rustls. | ||
| opendal = { version = "0.57" } | ||
| ``` | ||
|
|
||
| To select one transport TLS feature explicitly, disable default features: | ||
|
|
||
| ```toml | ||
| [dependencies] | ||
| opendal = { version = "0.57", default-features = false, features = [ | ||
| "http-transport-reqwest-rustls", | ||
| ] } | ||
| ``` | ||
|
|
||
| ## Build different TLS backends | ||
|
|
||
| ### Rustls | ||
|
|
||
| Use reqwest's Rustls backend explicitly when you build the client: | ||
|
|
||
| ```toml | ||
| [dependencies] | ||
| opendal = { version = "0.57", default-features = false, features = [ | ||
| "http-transport-reqwest-rustls", | ||
| ] } | ||
| reqwest = { version = "0.13.4", default-features = false, features = [ | ||
| "rustls", | ||
| "stream", | ||
| ] } | ||
| ``` | ||
|
|
||
| ```rust | ||
| use std::time::Duration; | ||
|
|
||
| use opendal::HttpTransporter; | ||
| use opendal::ReqwestTransport; | ||
|
|
||
| fn build_transport() -> Result<HttpTransporter, Box<dyn std::error::Error>> { | ||
| let client = reqwest::Client::builder() | ||
| .tls_backend_rustls() | ||
| .connect_timeout(Duration::from_secs(10)) | ||
| .build()?; | ||
|
|
||
| Ok(HttpTransporter::new(ReqwestTransport::new(client))) | ||
| } | ||
| ``` | ||
|
|
||
| ### Native TLS | ||
|
|
||
| Use `native-tls` when you want reqwest to delegate TLS to the platform stack: | ||
|
|
||
| ```toml | ||
| [dependencies] | ||
| opendal = { version = "0.57", default-features = false, features = [ | ||
| "http-transport-reqwest-native-tls", | ||
| ] } | ||
| reqwest = { version = "0.13.4", default-features = false, features = [ | ||
| "native-tls", | ||
| "stream", | ||
| ] } | ||
| ``` | ||
|
|
||
| ```rust | ||
| use opendal::HttpTransporter; | ||
| use opendal::ReqwestTransport; | ||
|
|
||
| fn build_transport() -> Result<HttpTransporter, Box<dyn std::error::Error>> { | ||
| let client = reqwest::Client::builder() | ||
| .tls_backend_native() | ||
| .build()?; | ||
|
|
||
| Ok(HttpTransporter::new(ReqwestTransport::new(client))) | ||
| } | ||
| ``` | ||
|
|
||
| ### rustls-no-provider | ||
|
|
||
| When using `wekpki-roots`, you could use `rustls-no-provider`. | ||
|
|
||
| Use `rustls-no-provider` when the application owns the Rustls provider and | ||
| certificate roots. This example only configures Mozilla roots from | ||
| `webpki-roots`; install or configure the Rustls crypto provider in application | ||
| startup. | ||
|
|
||
| ```toml | ||
| [dependencies] | ||
| opendal = { version = "0.57", default-features = false, features = [ | ||
| "http-transport-reqwest-rustls-no-provider", | ||
| ] } | ||
| reqwest = { version = "0.13.4", default-features = false, features = [ | ||
| "rustls-no-provider", | ||
| "stream", | ||
| ] } | ||
| rustls = { version = "0.23", default-features = false, features = ["std"] } | ||
| webpki-roots = "1" | ||
| ``` | ||
|
|
||
| ```rust | ||
| use opendal::HttpTransporter; | ||
| use opendal::ReqwestTransport; | ||
|
|
||
| fn build_transport() -> Result<HttpTransporter, Box<dyn std::error::Error>> { | ||
| let root_store = | ||
| rustls::RootCertStore::from_iter(webpki_roots::TLS_SERVER_ROOTS.iter().cloned()); | ||
|
|
||
| let tls_config = rustls::ClientConfig::builder() | ||
| .with_root_certificates(root_store) | ||
| .with_no_client_auth(); | ||
|
|
||
| let client = reqwest::Client::builder() | ||
| .tls_backend_preconfigured(tls_config) | ||
| .build()?; | ||
|
|
||
| Ok(HttpTransporter::new(ReqwestTransport::new(client))) | ||
| } | ||
| ``` | ||
|
|
||
| To use `ring` crate, please refer `rustls` documentation. | ||
|
|
||
| ## WASM targets | ||
|
|
||
| On `wasm32-unknown-unknown` and `wasm32-none`, reqwest switches to its WASM | ||
| client implementation. It uses the browser or host Fetch API instead of hyper. | ||
| TLS is provided by the browser or host environment, so the effective choice is | ||
| the system TLS stack exposed to that environment. | ||
|
|
||
| This means `native-tls`, `rustls`, `rustls-no-provider`, custom root stores, | ||
| and custom Rustls crypto providers do not select the TLS implementation for | ||
| wasm requests. See [reqwest's WASM documentation](https://docs.rs/reqwest/latest/reqwest/#wasm) | ||
| for the target-specific limitations. | ||
|
|
||
| ## License and Trademarks | ||
|
|
||
| Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| Apache OpenDAL, OpenDAL, and Apache are either registered trademarks or trademarks of the Apache Software Foundation. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.