Browse Source

storage: route OpenDAL through HTTP client

OpenDAL 0.58 requires applications to provide an HTTP transport. Its
default installer creates a standalone client, bypassing Vaultwarden
DNS, redirect, proxy, timeout, and request configuration.

Build the client through the internal HTTP interface and inject it into
OpenDAL's public reqwest transport.
pull/7639/head
Chase Douglas 2 weeks ago
parent
commit
8f690ca232
  1. 40
      Cargo.lock
  2. 2
      Cargo.toml
  3. 12
      src/storage.rs

40
Cargo.lock

@ -320,6 +320,16 @@ dependencies = [
"syn 3.0.3",
]
[[package]]
name = "asyncband"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94a214ba60d6231afd0e805e3c27c45a1626d9debaa5a5061c45a1ea1b2f1ed0"
dependencies = [
"hashbrown 0.17.1",
"slab",
]
[[package]]
name = "atomic"
version = "0.5.3"
@ -3100,15 +3110,6 @@ dependencies = [
"digest 0.11.3",
]
[[package]]
name = "mea"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31fc7d159de0085ab6dd7ff145a9819442cfd3d098f783263120503c3f3e58b0"
dependencies = [
"slab",
]
[[package]]
name = "memchr"
version = "2.8.3"
@ -3437,11 +3438,12 @@ dependencies = [
[[package]]
name = "opendal-core"
version = "0.58.1"
version = "0.58.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec75551ff4cf3e57da98979f6a937aaa9ddb3915bf68cc17d03df733be6646ed"
checksum = "48dbcef97d3eb7591db2c18d5cae95c836bcce07359b98d98dd6f4e861eb77b7"
dependencies = [
"anyhow",
"asyncband",
"base64 0.23.1",
"bytes",
"futures",
@ -3449,7 +3451,6 @@ dependencies = [
"jiff",
"log",
"md-5",
"mea",
"percent-encoding",
"quick-xml",
"reqsign-core",
@ -3461,6 +3462,20 @@ dependencies = [
"web-time",
]
[[package]]
name = "opendal-http-transport-reqwest"
version = "0.58.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85663452ea32bbc17e8f79ab29788c846d116ec7de31451be9c787e462dcb36c"
dependencies = [
"bytes",
"futures",
"http 1.5.0",
"http-body 1.1.0",
"opendal-core",
"reqwest",
]
[[package]]
name = "opendal-service-fs"
version = "0.58.1"
@ -5889,6 +5904,7 @@ dependencies = [
"num-derive",
"num-traits",
"opendal",
"opendal-http-transport-reqwest",
"openidconnect",
"openssl",
"pastey 0.2.3",

2
Cargo.toml

@ -41,6 +41,7 @@ vendored_openssl = ["openssl/vendored"]
enable_mimalloc = ["dep:mimalloc"]
s3 = [
"opendal/services-s3",
"dep:opendal-http-transport-reqwest",
"dep:aws-config",
"dep:aws-credential-types",
"dep:aws-smithy-runtime-api",
@ -258,6 +259,7 @@ grass_compiler = { version = "0.13.4", default-features = false }
# File are accessed through Apache OpenDAL
opendal = { version = "0.58.1", default-features = false, features = ["services-fs"] }
opendal-http-transport-reqwest = { version = "0.58.1", default-features = false, features = ["rustls-no-provider"], optional = true }
# For retrieving AWS credentials, including temporary SSO credentials
aws-config = { version = "1.10.1", optional = true, default-features = false, features = [

12
src/storage.rs

@ -77,10 +77,18 @@ pub(crate) fn operator_for_path(path: &str) -> Result<opendal::Operator, crate::
#[cfg(s3)]
mod s3 {
use std::sync::LazyLock;
use opendal_http_transport_reqwest::ReqwestTransport;
use reqwest::Url;
use crate::error::Error;
static HTTP_CLIENT: LazyLock<reqwest::Client> = LazyLock::new(|| {
// Storage endpoints are administrator-configured and may be private.
crate::http_client::get_reqwest_client_builder(false).build().expect("Failed to build OpenDAL HTTP client")
});
pub(super) fn is_uri(path: &str) -> bool {
path.starts_with("s3://")
}
@ -236,7 +244,9 @@ mod s3 {
builder.credential_provider_chain(ProvideCredentialChain::new().push(OpenDALS3CredentialProvider));
}
Ok(opendal::Operator::new(builder)?)
let http_transport = opendal::HttpTransporter::new(ReqwestTransport::new(HTTP_CLIENT.clone()));
let context = opendal::OperationContext::new().with_http_transport(http_transport);
Ok(opendal::Operator::new(builder)?.with_context(context))
}
fn uri_has_option(uri: &opendal::OperatorUri, names: &[&str]) -> bool {

Loading…
Cancel
Save