use std::sync::OnceLock;
pub(crate) fn user_agent() -> &'static str {
static UA: OnceLock<String> = OnceLock::new();
UA.get_or_init(|| {
let os = sysinfo::System::long_os_version()
.or_else(sysinfo::System::name)
.unwrap_or_else(|| std::env::consts::OS.to_owned());
format!(
"bestool/{} ({os}; {})",
env!("CARGO_PKG_VERSION"),
sysinfo::System::cpu_arch(),
)
})
}
pub(crate) fn client_builder() -> reqwest::ClientBuilder {
reqwest::Client::builder()
.user_agent(user_agent())
.tls_sslkeylogfile(true)
}
pub(crate) fn client() -> reqwest::Client {
client_builder()
.build()
.expect("failed to build bestool HTTP client")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn user_agent_has_product_and_os_comment() {
let ua = user_agent();
assert!(ua.starts_with("bestool/"), "unexpected user-agent: {ua}");
assert!(ua.contains('('), "expected OS comment in: {ua}");
assert!(ua.ends_with(')'), "expected OS comment in: {ua}");
assert!(
ua.contains(sysinfo::System::cpu_arch().as_str()),
"expected arch in: {ua}"
);
}
}