use std::time::Duration;
use ureq::Agent;
use ureq::tls::{RootCerts, TlsConfig, TlsProvider};
const HTTP_TIMEOUT: Duration = Duration::from_secs(30);
pub const MAX_API_RESPONSE_SIZE: u64 = 10 * 1024 * 1024;
pub const MAX_DOWNLOAD_SIZE: u64 = 50 * 1024 * 1024;
const ALLOWED_DOWNLOAD_HOSTS: &[&str] = &[
"github.com",
"api.github.com",
"objects.githubusercontent.com",
"github-releases.githubusercontent.com",
];
pub fn validate_download_url(url: &str) -> Result<(), String> {
let parsed = url::Url::parse(url).map_err(|e| format!("Invalid URL '{}': {}", url, e))?;
match parsed.scheme() {
"https" => {}
scheme => {
return Err(format!(
"Insecure URL scheme '{}' rejected; only HTTPS is allowed. \
URL: {}",
scheme, url
));
}
}
let host = parsed.host_str().unwrap_or("");
if !ALLOWED_DOWNLOAD_HOSTS.contains(&host) {
return Err(format!(
"URL host '{}' is not in the allowed list for download operations. \
Allowed hosts: {}. \
URL: {}",
host,
ALLOWED_DOWNLOAD_HOSTS.join(", "),
url
));
}
Ok(())
}
pub fn agent() -> Agent {
let tls_config = TlsConfig::builder()
.provider(TlsProvider::NativeTls)
.root_certs(RootCerts::PlatformVerifier)
.build();
Agent::config_builder()
.tls_config(tls_config)
.timeout_global(Some(HTTP_TIMEOUT))
.build()
.into()
}