Skip to content

Commit

Permalink
List all libcurl features with --version.
Browse files Browse the repository at this point in the history
  • Loading branch information
jcamiel committed Sep 22, 2022
1 parent 0e3d1a3 commit 8cd29a8
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 26 deletions.
100 changes: 76 additions & 24 deletions packages/hurl/src/http/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,56 +16,108 @@
*
*/

use std::collections::HashMap;

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CurlVersionInfo {
pub libraries: Vec<String>,
pub features: Vec<String>,
}

/// 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<String> {
/// 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<String> = 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
}
6 changes: 4 additions & 2 deletions packages/hurl/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit 8cd29a8

Please sign in to comment.