use std::env;
use std::time::Duration;
pub const DEFAULT_UPSTREAM_READ_TIMEOUT_SECS: u64 = 120;
#[must_use]
pub fn parse_upstream_read_timeout(value: Option<&str>) -> Option<Duration> {
let seconds = value
.and_then(|value| value.trim().parse::<u64>().ok())
.unwrap_or(DEFAULT_UPSTREAM_READ_TIMEOUT_SECS);
(seconds > 0).then(|| Duration::from_secs(seconds))
}
pub fn build_upstream_client() -> reqwest::Result<reqwest::Client> {
let mut builder = reqwest::Client::builder().redirect(reqwest::redirect::Policy::none());
if let Some(timeout) =
parse_upstream_read_timeout(env::var("UPSTREAM_READ_TIMEOUT_SECS").ok().as_deref())
{
builder = builder.read_timeout(timeout);
}
builder.build()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn upstream_reads_are_bounded_unless_explicitly_disabled() {
assert_eq!(
parse_upstream_read_timeout(None),
Some(Duration::from_secs(DEFAULT_UPSTREAM_READ_TIMEOUT_SECS))
);
assert_eq!(
parse_upstream_read_timeout(Some("30")),
Some(Duration::from_secs(30))
);
assert_eq!(parse_upstream_read_timeout(Some("0")), None);
assert_eq!(
parse_upstream_read_timeout(Some("not-a-number")),
Some(Duration::from_secs(DEFAULT_UPSTREAM_READ_TIMEOUT_SECS))
);
}
}