diff --git a/src/client/mod.rs b/src/client/mod.rs index 5b9f1f49..451ff040 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -54,6 +54,7 @@ pub(crate) mod parts; pub use http::*; use async_trait::async_trait; +use reqwest::dns::Resolve; use reqwest::header::{HeaderMap, HeaderValue}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -318,6 +319,14 @@ impl Certificate { } } +#[derive(Clone)] +struct DynResolver(Arc); + +impl std::fmt::Debug for DynResolver { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("DynResolver") + } +} /// HTTP client configuration for remote object stores #[derive(Debug, Clone)] pub struct ClientOptions { @@ -344,6 +353,7 @@ pub struct ClientOptions { http1_only: ConfigValue, http2_only: ConfigValue, randomize_addresses: ConfigValue, + dns_resolver: Option, } impl Default for ClientOptions { @@ -382,6 +392,7 @@ impl Default for ClientOptions { http1_only: true.into(), http2_only: Default::default(), randomize_addresses: true.into(), + dns_resolver: Default::default(), } } } @@ -755,6 +766,15 @@ impl ClientOptions { self } + /// Override the default DNS resolver with a custom [`reqwest::dns::Resolve`] implementation. + /// + /// When set, [`ClientConfigKey::RandomizeAddresses`] will be ignored. The provided + /// resolver is responsible for resolving, shuffling, caching, etc. + pub fn with_dns_resolver(mut self, resolver: Arc) -> Self { + self.dns_resolver = Some(DynResolver(resolver)); + self + } + /// Get the default headers defined through `ClientOptions::with_default_headers` pub fn get_default_headers(&self) -> Option<&HeaderMap> { self.default_headers.as_ref() @@ -880,7 +900,9 @@ impl ClientOptions { // size of objects. builder = builder.no_gzip().no_brotli().no_zstd().no_deflate(); - if self.randomize_addresses.get()? { + if let Some(resolver) = &self.dns_resolver { + builder = builder.dns_resolver2(resolver.0.clone()); + } else if self.randomize_addresses.get()? { builder = builder.dns_resolver(Arc::new(dns::ShuffleResolver)); }