mirror of
https://git.proxmox.com/git/rustc
synced 2026-03-28 00:20:46 +00:00
502 lines
16 KiB
Rust
502 lines
16 KiB
Rust
use std::ffi::CStr;
|
|
use std::fmt;
|
|
use std::str;
|
|
|
|
use libc::{c_char, c_int};
|
|
|
|
/// Version information about libcurl and the capabilities that it supports.
|
|
pub struct Version {
|
|
inner: *mut curl_sys::curl_version_info_data,
|
|
}
|
|
|
|
unsafe impl Send for Version {}
|
|
unsafe impl Sync for Version {}
|
|
|
|
/// An iterator over the list of protocols a version supports.
|
|
#[derive(Clone)]
|
|
pub struct Protocols<'a> {
|
|
cur: *const *const c_char,
|
|
_inner: &'a Version,
|
|
}
|
|
|
|
impl Version {
|
|
/// Returns the libcurl version that this library is currently linked against.
|
|
pub fn num() -> &'static str {
|
|
unsafe {
|
|
let s = CStr::from_ptr(curl_sys::curl_version() as *const _);
|
|
str::from_utf8(s.to_bytes()).unwrap()
|
|
}
|
|
}
|
|
|
|
/// Returns the libcurl version that this library is currently linked against.
|
|
pub fn get() -> Version {
|
|
unsafe {
|
|
let ptr = curl_sys::curl_version_info(curl_sys::CURLVERSION_NOW);
|
|
assert!(!ptr.is_null());
|
|
Version { inner: ptr }
|
|
}
|
|
}
|
|
|
|
/// Returns the human readable version string,
|
|
pub fn version(&self) -> &str {
|
|
unsafe { crate::opt_str((*self.inner).version).unwrap() }
|
|
}
|
|
|
|
/// Returns a numeric representation of the version number
|
|
///
|
|
/// This is a 24 bit number made up of the major number, minor, and then
|
|
/// patch number. For example 7.9.8 will return 0x070908.
|
|
pub fn version_num(&self) -> u32 {
|
|
unsafe { (*self.inner).version_num as u32 }
|
|
}
|
|
|
|
/// Returns true if this was built with the vendored version of libcurl.
|
|
pub fn vendored(&self) -> bool {
|
|
curl_sys::vendored()
|
|
}
|
|
|
|
/// Returns a human readable string of the host libcurl is built for.
|
|
///
|
|
/// This is discovered as part of the build environment.
|
|
pub fn host(&self) -> &str {
|
|
unsafe { crate::opt_str((*self.inner).host).unwrap() }
|
|
}
|
|
|
|
/// Returns whether libcurl supports IPv6
|
|
pub fn feature_ipv6(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_IPV6)
|
|
}
|
|
|
|
/// Returns whether libcurl supports SSL
|
|
pub fn feature_ssl(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_SSL)
|
|
}
|
|
|
|
/// Returns whether libcurl supports HTTP deflate via libz
|
|
pub fn feature_libz(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_LIBZ)
|
|
}
|
|
|
|
/// Returns whether libcurl supports HTTP NTLM
|
|
pub fn feature_ntlm(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_NTLM)
|
|
}
|
|
|
|
/// Returns whether libcurl supports HTTP GSSNEGOTIATE
|
|
pub fn feature_gss_negotiate(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_GSSNEGOTIATE)
|
|
}
|
|
|
|
/// Returns whether libcurl was built with debug capabilities
|
|
pub fn feature_debug(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_DEBUG)
|
|
}
|
|
|
|
/// Returns whether libcurl was built with SPNEGO authentication
|
|
pub fn feature_spnego(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_SPNEGO)
|
|
}
|
|
|
|
/// Returns whether libcurl was built with large file support
|
|
pub fn feature_largefile(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_LARGEFILE)
|
|
}
|
|
|
|
/// Returns whether libcurl was built with support for IDNA, domain names
|
|
/// with international letters.
|
|
pub fn feature_idn(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_IDN)
|
|
}
|
|
|
|
/// Returns whether libcurl was built with support for SSPI.
|
|
pub fn feature_sspi(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_SSPI)
|
|
}
|
|
|
|
/// Returns whether libcurl was built with asynchronous name lookups.
|
|
pub fn feature_async_dns(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_ASYNCHDNS)
|
|
}
|
|
|
|
/// Returns whether libcurl was built with support for character
|
|
/// conversions.
|
|
pub fn feature_conv(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_CONV)
|
|
}
|
|
|
|
/// Returns whether libcurl was built with support for TLS-SRP.
|
|
pub fn feature_tlsauth_srp(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_TLSAUTH_SRP)
|
|
}
|
|
|
|
/// Returns whether libcurl was built with support for NTLM delegation to
|
|
/// winbind helper.
|
|
pub fn feature_ntlm_wb(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_NTLM_WB)
|
|
}
|
|
|
|
/// Returns whether libcurl was built with support for unix domain socket
|
|
pub fn feature_unix_domain_socket(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_UNIX_SOCKETS)
|
|
}
|
|
|
|
/// Returns whether libcurl was built with support for HTTP2.
|
|
pub fn feature_http2(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_HTTP2)
|
|
}
|
|
|
|
/// Returns whether libcurl was built with support for HTTP3.
|
|
pub fn feature_http3(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_HTTP3)
|
|
}
|
|
|
|
/// Returns whether libcurl was built with support for Brotli.
|
|
pub fn feature_brotli(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_BROTLI)
|
|
}
|
|
|
|
/// Returns whether libcurl was built with support for Alt-Svc.
|
|
pub fn feature_altsvc(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_ALTSVC)
|
|
}
|
|
|
|
/// Returns whether libcurl was built with support for zstd
|
|
pub fn feature_zstd(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_ZSTD)
|
|
}
|
|
|
|
/// Returns whether libcurl was built with support for unicode
|
|
pub fn feature_unicode(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_UNICODE)
|
|
}
|
|
|
|
/// Returns whether libcurl was built with support for hsts
|
|
pub fn feature_hsts(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_HSTS)
|
|
}
|
|
|
|
/// Returns whether libcurl was built with support for gsasl
|
|
pub fn feature_gsasl(&self) -> bool {
|
|
self.flag(curl_sys::CURL_VERSION_GSASL)
|
|
}
|
|
|
|
fn flag(&self, flag: c_int) -> bool {
|
|
unsafe { (*self.inner).features & flag != 0 }
|
|
}
|
|
|
|
/// Returns the version of OpenSSL that is used, or None if there is no SSL
|
|
/// support.
|
|
pub fn ssl_version(&self) -> Option<&str> {
|
|
unsafe { crate::opt_str((*self.inner).ssl_version) }
|
|
}
|
|
|
|
/// Returns the version of libz that is used, or None if there is no libz
|
|
/// support.
|
|
pub fn libz_version(&self) -> Option<&str> {
|
|
unsafe { crate::opt_str((*self.inner).libz_version) }
|
|
}
|
|
|
|
/// Returns an iterator over the list of protocols that this build of
|
|
/// libcurl supports.
|
|
pub fn protocols(&self) -> Protocols {
|
|
unsafe {
|
|
Protocols {
|
|
_inner: self,
|
|
cur: (*self.inner).protocols,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// If available, the human readable version of ares that libcurl is linked
|
|
/// against.
|
|
pub fn ares_version(&self) -> Option<&str> {
|
|
unsafe {
|
|
if (*self.inner).age >= curl_sys::CURLVERSION_SECOND {
|
|
crate::opt_str((*self.inner).ares)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
/// If available, the version of ares that libcurl is linked against.
|
|
pub fn ares_version_num(&self) -> Option<u32> {
|
|
unsafe {
|
|
if (*self.inner).age >= curl_sys::CURLVERSION_SECOND {
|
|
Some((*self.inner).ares_num as u32)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
/// If available, the version of libidn that libcurl is linked against.
|
|
pub fn libidn_version(&self) -> Option<&str> {
|
|
unsafe {
|
|
if (*self.inner).age >= curl_sys::CURLVERSION_THIRD {
|
|
crate::opt_str((*self.inner).libidn)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
/// If available, the version of iconv libcurl is linked against.
|
|
pub fn iconv_version_num(&self) -> Option<u32> {
|
|
unsafe {
|
|
if (*self.inner).age >= curl_sys::CURLVERSION_FOURTH {
|
|
Some((*self.inner).iconv_ver_num as u32)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
/// If available, the version of libssh that libcurl is linked against.
|
|
pub fn libssh_version(&self) -> Option<&str> {
|
|
unsafe {
|
|
if (*self.inner).age >= curl_sys::CURLVERSION_FOURTH {
|
|
crate::opt_str((*self.inner).libssh_version)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
/// If available, the version of brotli libcurl is linked against.
|
|
pub fn brotli_version_num(&self) -> Option<u32> {
|
|
unsafe {
|
|
if (*self.inner).age >= curl_sys::CURLVERSION_FIFTH {
|
|
Some((*self.inner).brotli_ver_num)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
/// If available, the version of brotli libcurl is linked against.
|
|
pub fn brotli_version(&self) -> Option<&str> {
|
|
unsafe {
|
|
if (*self.inner).age >= curl_sys::CURLVERSION_FIFTH {
|
|
crate::opt_str((*self.inner).brotli_version)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
/// If available, the version of nghttp2 libcurl is linked against.
|
|
pub fn nghttp2_version_num(&self) -> Option<u32> {
|
|
unsafe {
|
|
if (*self.inner).age >= curl_sys::CURLVERSION_SIXTH {
|
|
Some((*self.inner).nghttp2_ver_num)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
/// If available, the version of nghttp2 libcurl is linked against.
|
|
pub fn nghttp2_version(&self) -> Option<&str> {
|
|
unsafe {
|
|
if (*self.inner).age >= curl_sys::CURLVERSION_SIXTH {
|
|
crate::opt_str((*self.inner).nghttp2_version)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
/// If available, the version of quic libcurl is linked against.
|
|
pub fn quic_version(&self) -> Option<&str> {
|
|
unsafe {
|
|
if (*self.inner).age >= curl_sys::CURLVERSION_SIXTH {
|
|
crate::opt_str((*self.inner).quic_version)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
/// If available, the built-in default of CURLOPT_CAINFO.
|
|
pub fn cainfo(&self) -> Option<&str> {
|
|
unsafe {
|
|
if (*self.inner).age >= curl_sys::CURLVERSION_SEVENTH {
|
|
crate::opt_str((*self.inner).cainfo)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
/// If available, the built-in default of CURLOPT_CAPATH.
|
|
pub fn capath(&self) -> Option<&str> {
|
|
unsafe {
|
|
if (*self.inner).age >= curl_sys::CURLVERSION_SEVENTH {
|
|
crate::opt_str((*self.inner).capath)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
/// If avaiable, the numeric zstd version
|
|
///
|
|
/// Represented as `(MAJOR << 24) | (MINOR << 12) | PATCH`
|
|
pub fn zstd_ver_num(&self) -> Option<u32> {
|
|
unsafe {
|
|
if (*self.inner).age >= curl_sys::CURLVERSION_EIGHTH {
|
|
Some((*self.inner).zstd_ver_num)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
/// If available, the human readable version of zstd
|
|
pub fn zstd_version(&self) -> Option<&str> {
|
|
unsafe {
|
|
if (*self.inner).age >= curl_sys::CURLVERSION_EIGHTH {
|
|
crate::opt_str((*self.inner).zstd_version)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
/// If available, the human readable version of hyper
|
|
pub fn hyper_version(&self) -> Option<&str> {
|
|
unsafe {
|
|
if (*self.inner).age >= curl_sys::CURLVERSION_NINTH {
|
|
crate::opt_str((*self.inner).hyper_version)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
/// If available, the human readable version of hyper
|
|
pub fn gsasl_version(&self) -> Option<&str> {
|
|
unsafe {
|
|
if (*self.inner).age >= curl_sys::CURLVERSION_TENTH {
|
|
crate::opt_str((*self.inner).gsasl_version)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl fmt::Debug for Version {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
let mut f = f.debug_struct("Version");
|
|
f.field("version", &self.version())
|
|
.field("rust_crate_version", &env!("CARGO_PKG_VERSION"))
|
|
.field("rust_sys_crate_version", &curl_sys::rust_crate_version())
|
|
.field("vendored", &self.vendored())
|
|
.field("host", &self.host())
|
|
.field("feature_ipv6", &self.feature_ipv6())
|
|
.field("feature_ssl", &self.feature_ssl())
|
|
.field("feature_libz", &self.feature_libz())
|
|
.field("feature_ntlm", &self.feature_ntlm())
|
|
.field("feature_gss_negotiate", &self.feature_gss_negotiate())
|
|
.field("feature_debug", &self.feature_debug())
|
|
.field("feature_spnego", &self.feature_spnego())
|
|
.field("feature_largefile", &self.feature_largefile())
|
|
.field("feature_idn", &self.feature_idn())
|
|
.field("feature_sspi", &self.feature_sspi())
|
|
.field("feature_async_dns", &self.feature_async_dns())
|
|
.field("feature_conv", &self.feature_conv())
|
|
.field("feature_tlsauth_srp", &self.feature_tlsauth_srp())
|
|
.field("feature_ntlm_wb", &self.feature_ntlm_wb())
|
|
.field(
|
|
"feature_unix_domain_socket",
|
|
&self.feature_unix_domain_socket(),
|
|
)
|
|
.field("feature_altsvc", &self.feature_altsvc())
|
|
.field("feature_zstd", &self.feature_zstd())
|
|
.field("feature_unicode", &self.feature_unicode())
|
|
.field("feature_http3", &self.feature_http3())
|
|
.field("feature_http2", &self.feature_http2())
|
|
.field("feature_gsasl", &self.feature_gsasl())
|
|
.field("feature_brotli", &self.feature_brotli());
|
|
|
|
if let Some(s) = self.ssl_version() {
|
|
f.field("ssl_version", &s);
|
|
}
|
|
if let Some(s) = self.libz_version() {
|
|
f.field("libz_version", &s);
|
|
}
|
|
if let Some(s) = self.ares_version() {
|
|
f.field("ares_version", &s);
|
|
}
|
|
if let Some(s) = self.libidn_version() {
|
|
f.field("libidn_version", &s);
|
|
}
|
|
if let Some(s) = self.iconv_version_num() {
|
|
f.field("iconv_version_num", &format!("{:x}", s));
|
|
}
|
|
if let Some(s) = self.libssh_version() {
|
|
f.field("libssh_version", &s);
|
|
}
|
|
if let Some(s) = self.brotli_version_num() {
|
|
f.field("brotli_version_num", &format!("{:x}", s));
|
|
}
|
|
if let Some(s) = self.brotli_version() {
|
|
f.field("brotli_version", &s);
|
|
}
|
|
if let Some(s) = self.nghttp2_version_num() {
|
|
f.field("nghttp2_version_num", &format!("{:x}", s));
|
|
}
|
|
if let Some(s) = self.nghttp2_version() {
|
|
f.field("nghttp2_version", &s);
|
|
}
|
|
if let Some(s) = self.quic_version() {
|
|
f.field("quic_version", &s);
|
|
}
|
|
if let Some(s) = self.zstd_ver_num() {
|
|
f.field("zstd_ver_num", &format!("{:x}", s));
|
|
}
|
|
if let Some(s) = self.zstd_version() {
|
|
f.field("zstd_version", &s);
|
|
}
|
|
if let Some(s) = self.cainfo() {
|
|
f.field("cainfo", &s);
|
|
}
|
|
if let Some(s) = self.capath() {
|
|
f.field("capath", &s);
|
|
}
|
|
if let Some(s) = self.hyper_version() {
|
|
f.field("hyper_version", &s);
|
|
}
|
|
if let Some(s) = self.gsasl_version() {
|
|
f.field("gsasl_version", &s);
|
|
}
|
|
|
|
f.field("protocols", &self.protocols().collect::<Vec<_>>());
|
|
|
|
f.finish()
|
|
}
|
|
}
|
|
|
|
impl<'a> Iterator for Protocols<'a> {
|
|
type Item = &'a str;
|
|
|
|
fn next(&mut self) -> Option<&'a str> {
|
|
unsafe {
|
|
if (*self.cur).is_null() {
|
|
return None;
|
|
}
|
|
let ret = crate::opt_str(*self.cur).unwrap();
|
|
self.cur = self.cur.offset(1);
|
|
Some(ret)
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> fmt::Debug for Protocols<'a> {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
f.debug_list().entries(self.clone()).finish()
|
|
}
|
|
}
|