From 8cd29a8a9e2589acf1722815e95d8bd9ebc72cfa Mon Sep 17 00:00:00 2001 From: jcamiel Date: Tue, 20 Sep 2022 10:24:27 +0200 Subject: [PATCH] List all libcurl features with --version. --- packages/hurl/src/http/version.rs | 100 +++++++++++++++++++++++------- packages/hurl/src/main.rs | 6 +- 2 files changed, 80 insertions(+), 26 deletions(-) diff --git a/packages/hurl/src/http/version.rs b/packages/hurl/src/http/version.rs index 4144bf4fa2a..9140a983143 100644 --- a/packages/hurl/src/http/version.rs +++ b/packages/hurl/src/http/version.rs @@ -16,56 +16,108 @@ * */ +use std::collections::HashMap; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct CurlVersionInfo { + pub libraries: Vec, + pub features: Vec, +} + +/// Returns the libraries and features of libcurl. /// -/// get libcurl version -/// -// Output should be similar to curl -// https://github.com/curl/curl/blob/master/lib/version.c -// -// Remarks: -// 1) you must make the data returned from libcurl uniform: prefix, string version -// 2) can not find libpsl info in curl crate -// -pub fn libcurl_version_info() -> Vec { +/// Output should be similar to `curl --version` +/// - https://github.com/curl/curl/blob/master/lib/version.c +/// - https://github.com/curl/curl/blob/master/src/tool_help.c +pub fn libcurl_version_info() -> CurlVersionInfo { let version = curl::Version::get(); - let mut versions = vec![format!("libcurl/{}", version.version())]; + let mut libraries = vec![format!("libcurl/{}", version.version())]; if let Some(s) = version.ssl_version() { - versions.push(s.to_string()); + libraries.push(s.to_string()); } if let Some(s) = version.libz_version() { - versions.push(format!("zlib/{}", s)); + libraries.push(format!("zlib/{}", s)); } if let Some(s) = version.brotli_version() { - versions.push(format!("brotli/{}", s)); + libraries.push(format!("brotli/{}", s)); } if let Some(s) = version.zstd_version() { - versions.push(format!("zstd/{}", s)); + libraries.push(format!("zstd/{}", s)); } if let Some(s) = version.ares_version() { - versions.push(format!("c-ares/{}", s)); + libraries.push(format!("c-ares/{}", s)); } if let Some(s) = version.libidn_version() { - versions.push(format!("libidn2/{}", s)); + libraries.push(format!("libidn2/{}", s)); } if let Some(s) = version.iconv_version_num() { if s != 0 { - versions.push(format!("iconv/{}", s)); + libraries.push(format!("iconv/{}", s)); } } if let Some(s) = version.libssh_version() { - versions.push(format!("libssh/{}", s)); + libraries.push(s.to_string()); } if let Some(s) = version.nghttp2_version() { - versions.push(format!("nghttp2/{}", s)); + libraries.push(format!("nghttp2/{}", s)); } if let Some(s) = version.quic_version() { - versions.push(format!("quic/{}", s)); + libraries.push(format!("quic/{}", s)); } if let Some(s) = version.hyper_version() { - versions.push(format!("hyper/{}", s)); + libraries.push(format!("hyper/{}", s)); } if let Some(s) = version.gsasl_version() { - versions.push(format!("libgsal/{}", s)); + libraries.push(format!("libgsal/{}", s)); + } + + // FIXME: some flags are not present in crates curl-rust. + // See https://github.com/alexcrichton/curl-rust/issues/464 + // See https://github.com/curl/curl/blob/master/include/curl/curl.h for all curl flags + // See https://github.com/alexcrichton/curl-rust/blob/main/curl-sys/lib.rs for curl-rust flags + // Not defined in curl-rust: + // - CURL_VERSION_GSSAPI (1<<17) + // - CURL_VERSION_KERBEROS5 (1<<18) + // - CURL_VERSION_PSL (1<<20) + // - CURL_VERSION_HTTPS_PROXY (1<<21) + // - CURL_VERSION_MULTI_SSL (1<<22) + // - CURL_VERSION_THREADSAFE (1<<30) + + let all_features = HashMap::from([ + ("AsynchDNS", version.feature_async_dns()), + ("Debug", version.feature_debug()), + ("IDN", version.feature_idn()), + ("IPv6", version.feature_ipv6()), + ("Largefile", version.feature_largefile()), + ("Unicode", version.feature_unicode()), + ("SSPI", version.feature_sspi()), + ("SPNEGO", version.feature_spnego()), + ("NTLM", version.feature_ntlm()), + ("NTLM_WB", version.feature_ntlm_wb()), + ("SSL", version.feature_ssl()), + ("libz", version.feature_libz()), + ("brotli", version.feature_brotli()), + ("zstd", version.feature_zstd()), + ("CharConv", version.feature_conv()), + ("TLS-SRP", version.feature_tlsauth_srp()), + ("HTTP2", version.feature_http2()), + ("HTTP3", version.feature_http3()), + ("UnixSockets", version.feature_unix_domain_socket()), + ("alt-svc", version.feature_altsvc()), + ("HSTS", version.feature_hsts()), + ("gsasl", version.feature_gsasl()), + ("GSS-Negotiate", version.feature_gss_negotiate()), + ]); + let mut features: Vec = vec![]; + for (k, v) in all_features.iter() { + if *v { + features.push(k.to_string()); + } + } + features.sort_by_key(|k| k.to_lowercase()); + + CurlVersionInfo { + libraries, + features, } - versions } diff --git a/packages/hurl/src/main.rs b/packages/hurl/src/main.rs index 55c7c684ec2..ed00eafff45 100644 --- a/packages/hurl/src/main.rs +++ b/packages/hurl/src/main.rs @@ -239,10 +239,12 @@ fn exit_with_error(message: &str, code: i32, logger: &BaseLogger) -> ! { } /// Executes Hurl entry point. fn main() { + let libcurl_version = http::libcurl_version_info(); let version_info = format!( - "{} {}", + "{} {}\nFeatures (libcurl): {}\nFeatures (built-in): brotli", clap::crate_version!(), - http::libcurl_version_info().join(" ") + libcurl_version.libraries.join(" "), + libcurl_version.features.join(" "), ); let app = cli::app(version_info.as_str()); let matches = app.clone().get_matches();