1use once_cell::sync::Lazy;
4
5static CURL_VERSION: Lazy<curl::Version> = Lazy::new(curl::Version::get);
7
8pub fn version() -> &'static str {
14 static VERSION_STRING: Lazy<String> = Lazy::new(|| {
15 format!(
16 "isahc/{} (features:{}) {}",
17 env!("CARGO_PKG_VERSION"),
18 env!("ISAHC_FEATURES"),
19 curl::Version::num(),
20 )
21 });
22
23 &VERSION_STRING
24}
25
26pub fn is_http_version_supported(version: http::Version) -> bool {
37 match version {
38 http::Version::HTTP_09 => match curl_version() {
42 (7, minor, _) if minor < 66 => true,
43 (major, _, _) if major < 7 => true,
44 _ => false,
45 },
46 http::Version::HTTP_10 => true,
47 http::Version::HTTP_11 => true,
48 http::Version::HTTP_2 => CURL_VERSION.feature_http2(),
49 http::Version::HTTP_3 => CURL_VERSION.feature_http3(),
50 _ => false,
51 }
52}
53
54fn curl_version() -> (u8, u8, u8) {
55 let bits = CURL_VERSION.version_num();
56
57 ((bits >> 16) as u8, (bits >> 8) as u8, bits as u8)
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn version_expected() {
66 let version = version();
67
68 assert!(version.starts_with("isahc/1."));
69 assert!(version.contains("curl/7."));
70 }
71
72 #[test]
73 fn curl_version_expected() {
74 let (major, minor, _patch) = curl_version();
75
76 assert_eq!(major, 7);
77 assert!(minor > 0);
78 }
79
80 #[test]
81 fn http1_always_supported() {
82 assert!(is_http_version_supported(http::Version::HTTP_10));
83 assert!(is_http_version_supported(http::Version::HTTP_11));
84
85 if cfg!(feature = "http2") {
86 assert!(is_http_version_supported(http::Version::HTTP_2));
87 }
88 }
89}