use std::sync::LazyLock;
pub fn version() -> &'static str {
static VERSION_STRING: LazyLock<String> = LazyLock::new(|| {
format!(
"isahc/{} (features:{}) {}",
env!("CARGO_PKG_VERSION"),
env!("ISAHC_FEATURES"),
curl::Version::num(),
)
});
&VERSION_STRING
}
pub fn is_http_version_supported(version: http::Version) -> bool {
match version {
http::Version::HTTP_09 => curl_version() < (7, 66, 0),
http::Version::HTTP_10 => true,
http::Version::HTTP_11 => true,
http::Version::HTTP_2 => curl_info().feature_http2(),
http::Version::HTTP_3 => curl_info().feature_http3(),
_ => false,
}
}
#[inline]
pub(crate) fn curl_info() -> &'static curl::Version {
static CURL_VERSION: LazyLock<curl::Version> = LazyLock::new(curl::Version::get);
&CURL_VERSION
}
pub(crate) fn curl_version() -> (u8, u8, u8) {
let bits = curl_info().version_num();
((bits >> 16) as u8, (bits >> 8) as u8, bits as u8)
}
pub(crate) fn do_curl_sanity_checks() {
if curl_version() == (8, 20, 0) {
panic!("libcurl 8.20.0 detected, this version has a known bug that causes DNS to hang");
}
if !curl_info().protocols().any(|p| p == "http") {
panic!("linked libcurl does not support HTTP");
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn version_expected() {
let version = version();
assert!(version.starts_with(&format!("isahc/{}", env!("CARGO_PKG_VERSION"))));
assert!(version.contains("curl/7.") || version.contains("curl/8."));
}
#[test]
fn curl_version_expected() {
let (major, minor, _patch) = curl_version();
assert!(major >= 7);
assert!(minor > 0);
}
#[test]
fn http1_always_supported() {
assert!(is_http_version_supported(http::Version::HTTP_10));
assert!(is_http_version_supported(http::Version::HTTP_11));
if cfg!(feature = "http2") {
assert!(is_http_version_supported(http::Version::HTTP_2));
}
}
}