use std::time::Duration;
pub(crate) fn env_timeout(var: &str, default_secs: u64) -> Duration {
Duration::from_secs(
std::env::var(var)
.ok()
.and_then(|value| value.parse::<u64>().ok())
.unwrap_or(default_secs),
)
}
pub(crate) fn is_cloud(deploy_mode_var: &str, base_url: &str, cloud_host_marker: &str) -> bool {
let explicit = std::env::var(deploy_mode_var)
.map(|value| value.eq_ignore_ascii_case("cloud"))
.unwrap_or(false);
let host_match = !cloud_host_marker.is_empty() && base_url.contains(cloud_host_marker);
explicit || host_match
}
#[derive(Debug, Clone, Default)]
pub(crate) struct HttpClientSpec {
pub timeout: Option<Duration>,
pub connect_timeout: Option<Duration>,
pub https_only: bool,
}
impl HttpClientSpec {
pub(crate) fn with_timeout(timeout: Duration) -> Self {
Self {
timeout: Some(timeout),
..Self::default()
}
}
pub(crate) fn with_connect_timeout(connect_timeout: Duration) -> Self {
Self {
connect_timeout: Some(connect_timeout),
..Self::default()
}
}
pub(crate) fn https_only(mut self, enabled: bool) -> Self {
self.https_only = enabled;
self
}
pub(crate) fn build(&self) -> reqwest::Client {
let mut builder = reqwest::Client::builder();
if let Some(timeout) = self.timeout {
builder = builder.timeout(timeout);
}
if let Some(connect_timeout) = self.connect_timeout {
builder = builder.connect_timeout(connect_timeout);
}
if self.https_only {
builder = builder.https_only(true);
}
builder.build().unwrap_or_default()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn is_cloud_detects_host_marker_when_mode_unset() {
let var = "UDB_TEST_HTTP_DEPLOY_MODE_HOST_UNSET";
assert!(is_cloud(
var,
"https://abc.clickhouse.cloud",
".clickhouse.cloud"
));
assert!(!is_cloud(
var,
"https://abc.example.com",
".clickhouse.cloud"
));
assert!(!is_cloud(var, "http://localhost", ""));
}
#[test]
fn env_timeout_falls_back_to_default() {
let var = "UDB_TEST_HTTP_TIMEOUT_UNSET";
assert_eq!(env_timeout(var, 30), Duration::from_secs(30));
}
#[test]
fn spec_builds_clients() {
let _ = HttpClientSpec::with_timeout(Duration::from_secs(5)).build();
let _ = HttpClientSpec::with_connect_timeout(Duration::from_secs(5))
.https_only(true)
.build();
}
}