use crate::{ config, config::tree::{keys, Http, Key, Section},}; impl Http { /// The `http.sslVersion` key. pub const SSL_VERSION: SslVersion = SslVersion::new_ssl_version("sslVersion", &config::Tree::HTTP) .with_environment_override("GIT_SSL_VERSION") .with_deviation( "accepts the new 'default' value which means to use the curl default just like the empty string does", ); /// The `http.proxy` key. pub const PROXY: keys::String = keys::String::new_string("proxy", &config::Tree::HTTP).with_deviation("fails on strings with illformed UTF-8"); /// The `http.proxyAuthMethod` key. pub const PROXY_AUTH_METHOD: ProxyAuthMethod = ProxyAuthMethod::new_proxy_auth_method("proxyAuthMethod", &config::Tree::HTTP) .with_deviation("implemented like git, but never actually tried"); /// The `http.version` key. pub const VERSION: Version = Version::new_with_validate("version", &config::Tree::HTTP, validate::Version) .with_deviation("fails on illformed UTF-8"); /// The `http.userAgent` key. pub const USER_AGENT: keys::String = keys::String::new_string("userAgent", &config::Tree::HTTP).with_deviation("fails on illformed UTF-8"); /// The `http.extraHeader` key. pub const EXTRA_HEADER: ExtraHeader = ExtraHeader::new_with_validate("extraHeader", &config::Tree::HTTP, validate::ExtraHeader) .with_deviation("fails on illformed UTF-8, without leniency"); /// The `http.followRedirects` key. pub const FOLLOW_REDIRECTS: FollowRedirects = FollowRedirects::new_with_validate("followRedirects", &config::Tree::HTTP, validate::FollowRedirects); /// The `http.lowSpeedTime` key. pub const LOW_SPEED_TIME: keys::UnsignedInteger = keys::UnsignedInteger::new_unsigned_integer("lowSpeedTime", &config::Tree::HTTP) .with_deviation("fails on negative values"); /// The `http.lowSpeedLimit` key. pub const LOW_SPEED_LIMIT: keys::UnsignedInteger = keys::UnsignedInteger::new_unsigned_integer("lowSpeedLimit", &config::Tree::HTTP) .with_deviation("fails on negative values"); /// The `http.schannelUseSSLCAInfo` key. pub const SCHANNEL_USE_SSL_CA_INFO: keys::Boolean = keys::Boolean::new_boolean("schannelUseSSLCAInfo", &config::Tree::HTTP) .with_deviation("only used as switch internally to turn off using the sslCAInfo, unconditionally. If unset, it has no effect, whereas in `git` it defaults to false."); /// The `http.sslCAInfo` key. pub const SSL_CA_INFO: keys::Path = keys::Path::new_path("sslCAInfo", &config::Tree::HTTP).with_environment_override("GIT_SSL_CAINFO"); /// The `http.schannelCheckRevoke` key. pub const SCHANNEL_CHECK_REVOKE: keys::Boolean = keys::Boolean::new_boolean("schannelCheckRevoke", &config::Tree::HTTP);} impl Section for Http { fn name(&self) -> &str { "http" } fn keys(&self) -> &[&dyn Key] { &[ &Self::SSL_VERSION, &Self::PROXY, &Self::PROXY_AUTH_METHOD, &Self::VERSION, &Self::USER_AGENT, &Self::EXTRA_HEADER, &Self::FOLLOW_REDIRECTS, &Self::LOW_SPEED_TIME, &Self::LOW_SPEED_LIMIT, &Self::SCHANNEL_USE_SSL_CA_INFO, &Self::SSL_CA_INFO, &Self::SCHANNEL_CHECK_REVOKE, ] }} /// The `http.followRedirects` key.pub type FollowRedirects = keys::Any<validate::FollowRedirects>; /// The `http.extraHeader` key.pub type ExtraHeader = keys::Any<validate::ExtraHeader>; /// The `http.sslVersion` key, as well as others of the same type.pub type SslVersion = keys::Any<validate::SslVersion>; /// The `http.proxyAuthMethod` key, as well as others of the same type.pub type ProxyAuthMethod = keys::Any<validate::ProxyAuthMethod>; /// The `http.version` key.pub type Version = keys::Any<validate::Version>; mod key_impls { use crate::config::tree::{ http::{ProxyAuthMethod, SslVersion}, keys, Section, }; impl SslVersion { pub const fn new_ssl_version(name: &'static str, section: &'static dyn Section) -> Self { keys::Any::new_with_validate(name, section, super::validate::SslVersion) } } impl ProxyAuthMethod { pub const fn new_proxy_auth_method(name: &'static str, section: &'static dyn Section) -> Self { keys::Any::new_with_validate(name, section, super::validate::ProxyAuthMethod) } } #[cfg(any( feature = "blocking-http-transport-reqwest", feature = "blocking-http-transport-curl" ))] impl crate::config::tree::http::FollowRedirects { /// Convert `value` into the redirect specification, or query the same value as `boolean` /// for additional possible input values. /// /// Note that `boolean` only queries the underlying key as boolean, which is a necessity to handle /// empty booleans correctly, that is those without a value separator. pub fn try_into_follow_redirects( &'static self, value: std::borrow::Cow<'_, crate::bstr::BStr>, boolean: impl FnOnce() -> Result<Option<bool>, git_config::value::Error>, ) -> Result< crate::protocol::transport::client::http::options::FollowRedirects, crate::config::key::GenericErrorWithValue, > { use crate::protocol::transport::client::http::options::FollowRedirects; Ok(if value.as_ref().as_ref() == b"initial" { FollowRedirects::Initial } else if let Some(value) = boolean().map_err(|err| { crate::config::key::GenericErrorWithValue::from_value(self, value.into_owned()).with_source(err) })? { if value { FollowRedirects::All } else { FollowRedirects::None } } else { FollowRedirects::Initial }) } } impl super::ExtraHeader { /// Convert a list of values into extra-headers, while failing entirely on illformed UTF-8. pub fn try_into_extra_header( &'static self, values: Vec<std::borrow::Cow<'_, crate::bstr::BStr>>, ) -> Result<Vec<String>, crate::config::string::Error> { let mut out = Vec::with_capacity(values.len()); for value in values { if value.is_empty() { out.clear(); } else { out.push(self.try_into_string(value)?); } } Ok(out) } } #[cfg(any( feature = "blocking-http-transport-reqwest", feature = "blocking-http-transport-curl" ))] impl super::Version { pub fn try_into_http_version( &'static self, value: std::borrow::Cow<'_, crate::bstr::BStr>, ) -> Result< git_protocol::transport::client::http::options::HttpVersion, crate::config::key::GenericErrorWithValue, > { use git_protocol::transport::client::http::options::HttpVersion; Ok(match value.as_ref().as_ref() { b"HTTP/1.1" => HttpVersion::V1_1, b"HTTP/2" => HttpVersion::V2, _ => { return Err(crate::config::key::GenericErrorWithValue::from_value( self, value.into_owned(), )) } }) } } #[cfg(any( feature = "blocking-http-transport-reqwest", feature = "blocking-http-transport-curl" ))] impl ProxyAuthMethod { pub fn try_into_proxy_auth_method( &'static self, value: std::borrow::Cow<'_, crate::bstr::BStr>, ) -> Result< git_protocol::transport::client::http::options::ProxyAuthMethod, crate::config::key::GenericErrorWithValue, > { use git_protocol::transport::client::http::options::ProxyAuthMethod; Ok(match value.as_ref().as_ref() { b"anyauth" => ProxyAuthMethod::AnyAuth, b"basic" => ProxyAuthMethod::Basic, b"digest" => ProxyAuthMethod::Digest, b"negotiate" => ProxyAuthMethod::Negotiate, b"ntlm" => ProxyAuthMethod::Ntlm, _ => { return Err(crate::config::key::GenericErrorWithValue::from_value( self, value.into_owned(), )) } }) } } #[cfg(any( feature = "blocking-http-transport-reqwest", feature = "blocking-http-transport-curl" ))] impl SslVersion { pub fn try_into_ssl_version( &'static self, value: std::borrow::Cow<'_, crate::bstr::BStr>, ) -> Result<git_protocol::transport::client::http::options::SslVersion, crate::config::ssl_version::Error> { use git_protocol::transport::client::http::options::SslVersion::*; Ok(match value.as_ref().as_ref() { b"default" | b"" => Default, b"tlsv1" => TlsV1, b"sslv2" => SslV2, b"sslv3" => SslV3, b"tlsv1.0" => TlsV1_0, b"tlsv1.1" => TlsV1_1, b"tlsv1.2" => TlsV1_2, b"tlsv1.3" => TlsV1_3, _ => return Err(crate::config::ssl_version::Error::from_value(self, value.into_owned())), }) } }} pub mod validate { use std::error::Error; use crate::{ bstr::{BStr, ByteSlice}, config::tree::keys::Validate, }; pub struct SslVersion; impl Validate for SslVersion { fn validate(&self, _value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> { #[cfg(any( feature = "blocking-http-transport-reqwest", feature = "blocking-http-transport-curl" ))] super::Http::SSL_VERSION.try_into_ssl_version(std::borrow::Cow::Borrowed(_value))?; Ok(()) } } pub struct ProxyAuthMethod; impl Validate for ProxyAuthMethod { fn validate(&self, _value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> { #[cfg(any( feature = "blocking-http-transport-reqwest", feature = "blocking-http-transport-curl" ))] super::Http::PROXY_AUTH_METHOD.try_into_proxy_auth_method(std::borrow::Cow::Borrowed(_value))?; Ok(()) } } pub struct Version; impl Validate for Version { fn validate(&self, _value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> { #[cfg(any( feature = "blocking-http-transport-reqwest", feature = "blocking-http-transport-curl" ))] super::Http::VERSION.try_into_http_version(std::borrow::Cow::Borrowed(_value))?; Ok(()) } } pub struct ExtraHeader; impl Validate for ExtraHeader { fn validate(&self, value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> { value.to_str()?; Ok(()) } } pub struct FollowRedirects; impl Validate for FollowRedirects { fn validate(&self, _value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> { #[cfg(any( feature = "blocking-http-transport-reqwest", feature = "blocking-http-transport-curl" ))] super::Http::FOLLOW_REDIRECTS.try_into_follow_redirects(std::borrow::Cow::Borrowed(_value), || { git_config::Boolean::try_from(_value).map(|b| Some(b.0)) })?; Ok(()) } }}
use crate::{
config,
config::tree::{keys, Http, Key, Section},
};
impl Http {
/// The `http.sslVersion` key.
pub const SSL_VERSION: SslVersion = SslVersion::new_ssl_version("sslVersion", &config::Tree::HTTP)
.with_environment_override("GIT_SSL_VERSION")
.with_deviation(
"accepts the new 'default' value which means to use the curl default just like the empty string does",
);
/// The `http.proxy` key.
pub const PROXY: keys::String =
keys::String::new_string("proxy", &config::Tree::HTTP).with_deviation("fails on strings with illformed UTF-8");
/// The `http.proxyAuthMethod` key.
pub const PROXY_AUTH_METHOD: ProxyAuthMethod =
ProxyAuthMethod::new_proxy_auth_method("proxyAuthMethod", &config::Tree::HTTP)
.with_deviation("implemented like git, but never actually tried");
/// The `http.version` key.
pub const VERSION: Version = Version::new_with_validate("version", &config::Tree::HTTP, validate::Version)
.with_deviation("fails on illformed UTF-8");
/// The `http.userAgent` key.
pub const USER_AGENT: keys::String =
keys::String::new_string("userAgent", &config::Tree::HTTP).with_deviation("fails on illformed UTF-8");
/// The `http.extraHeader` key.
pub const EXTRA_HEADER: ExtraHeader =
ExtraHeader::new_with_validate("extraHeader", &config::Tree::HTTP, validate::ExtraHeader)
.with_deviation("fails on illformed UTF-8, without leniency");
/// The `http.followRedirects` key.
pub const FOLLOW_REDIRECTS: FollowRedirects =
FollowRedirects::new_with_validate("followRedirects", &config::Tree::HTTP, validate::FollowRedirects);
/// The `http.lowSpeedTime` key.
pub const LOW_SPEED_TIME: keys::UnsignedInteger =
keys::UnsignedInteger::new_unsigned_integer("lowSpeedTime", &config::Tree::HTTP)
.with_deviation("fails on negative values");
/// The `http.lowSpeedLimit` key.
pub const LOW_SPEED_LIMIT: keys::UnsignedInteger =
keys::UnsignedInteger::new_unsigned_integer("lowSpeedLimit", &config::Tree::HTTP)
.with_deviation("fails on negative values");
/// The `http.schannelUseSSLCAInfo` key.
pub const SCHANNEL_USE_SSL_CA_INFO: keys::Boolean =
keys::Boolean::new_boolean("schannelUseSSLCAInfo", &config::Tree::HTTP)
.with_deviation("only used as switch internally to turn off using the sslCAInfo, unconditionally. If unset, it has no effect, whereas in `git` it defaults to false.");
/// The `http.sslCAInfo` key.
pub const SSL_CA_INFO: keys::Path =
keys::Path::new_path("sslCAInfo", &config::Tree::HTTP).with_environment_override("GIT_SSL_CAINFO");
/// The `http.schannelCheckRevoke` key.
pub const SCHANNEL_CHECK_REVOKE: keys::Boolean =
keys::Boolean::new_boolean("schannelCheckRevoke", &config::Tree::HTTP);
}
impl Section for Http {
fn name(&self) -> &str {
"http"
}
fn keys(&self) -> &[&dyn Key] {
&[
&Self::SSL_VERSION,
&Self::PROXY,
&Self::PROXY_AUTH_METHOD,
&Self::VERSION,
&Self::USER_AGENT,
&Self::EXTRA_HEADER,
&Self::FOLLOW_REDIRECTS,
&Self::LOW_SPEED_TIME,
&Self::LOW_SPEED_LIMIT,
&Self::SCHANNEL_USE_SSL_CA_INFO,
&Self::SSL_CA_INFO,
&Self::SCHANNEL_CHECK_REVOKE,
]
}
}
/// The `http.followRedirects` key.
pub type FollowRedirects = keys::Any<validate::FollowRedirects>;
/// The `http.extraHeader` key.
pub type ExtraHeader = keys::Any<validate::ExtraHeader>;
/// The `http.sslVersion` key, as well as others of the same type.
pub type SslVersion = keys::Any<validate::SslVersion>;
/// The `http.proxyAuthMethod` key, as well as others of the same type.
pub type ProxyAuthMethod = keys::Any<validate::ProxyAuthMethod>;
/// The `http.version` key.
pub type Version = keys::Any<validate::Version>;
mod key_impls {
use crate::config::tree::{
http::{ProxyAuthMethod, SslVersion},
keys, Section,
};
impl SslVersion {
pub const fn new_ssl_version(name: &'static str, section: &'static dyn Section) -> Self {
keys::Any::new_with_validate(name, section, super::validate::SslVersion)
}
}
impl ProxyAuthMethod {
pub const fn new_proxy_auth_method(name: &'static str, section: &'static dyn Section) -> Self {
keys::Any::new_with_validate(name, section, super::validate::ProxyAuthMethod)
}
}
#[cfg(any(
feature = "blocking-http-transport-reqwest",
feature = "blocking-http-transport-curl"
))]
impl crate::config::tree::http::FollowRedirects {
/// Convert `value` into the redirect specification, or query the same value as `boolean`
/// for additional possible input values.
///
/// Note that `boolean` only queries the underlying key as boolean, which is a necessity to handle
/// empty booleans correctly, that is those without a value separator.
pub fn try_into_follow_redirects(
&'static self,
value: std::borrow::Cow<'_, crate::bstr::BStr>,
boolean: impl FnOnce() -> Result<Option<bool>, git_config::value::Error>,
) -> Result<
crate::protocol::transport::client::http::options::FollowRedirects,
crate::config::key::GenericErrorWithValue,
> {
use crate::protocol::transport::client::http::options::FollowRedirects;
Ok(if value.as_ref().as_ref() == b"initial" {
FollowRedirects::Initial
} else if let Some(value) = boolean().map_err(|err| {
crate::config::key::GenericErrorWithValue::from_value(self, value.into_owned()).with_source(err)
})? {
if value {
FollowRedirects::All
} else {
FollowRedirects::None
}
} else {
FollowRedirects::Initial
})
}
}
impl super::ExtraHeader {
/// Convert a list of values into extra-headers, while failing entirely on illformed UTF-8.
pub fn try_into_extra_header(
&'static self,
values: Vec<std::borrow::Cow<'_, crate::bstr::BStr>>,
) -> Result<Vec<String>, crate::config::string::Error> {
let mut out = Vec::with_capacity(values.len());
for value in values {
if value.is_empty() {
out.clear();
} else {
out.push(self.try_into_string(value)?);
}
}
Ok(out)
}
}
#[cfg(any(
feature = "blocking-http-transport-reqwest",
feature = "blocking-http-transport-curl"
))]
impl super::Version {
pub fn try_into_http_version(
&'static self,
value: std::borrow::Cow<'_, crate::bstr::BStr>,
) -> Result<
git_protocol::transport::client::http::options::HttpVersion,
crate::config::key::GenericErrorWithValue,
> {
use git_protocol::transport::client::http::options::HttpVersion;
Ok(match value.as_ref().as_ref() {
b"HTTP/1.1" => HttpVersion::V1_1,
b"HTTP/2" => HttpVersion::V2,
_ => {
return Err(crate::config::key::GenericErrorWithValue::from_value(
self,
value.into_owned(),
))
}
})
}
}
#[cfg(any(
feature = "blocking-http-transport-reqwest",
feature = "blocking-http-transport-curl"
))]
impl ProxyAuthMethod {
pub fn try_into_proxy_auth_method(
&'static self,
value: std::borrow::Cow<'_, crate::bstr::BStr>,
) -> Result<
git_protocol::transport::client::http::options::ProxyAuthMethod,
crate::config::key::GenericErrorWithValue,
> {
use git_protocol::transport::client::http::options::ProxyAuthMethod;
Ok(match value.as_ref().as_ref() {
b"anyauth" => ProxyAuthMethod::AnyAuth,
b"basic" => ProxyAuthMethod::Basic,
b"digest" => ProxyAuthMethod::Digest,
b"negotiate" => ProxyAuthMethod::Negotiate,
b"ntlm" => ProxyAuthMethod::Ntlm,
_ => {
return Err(crate::config::key::GenericErrorWithValue::from_value(
self,
value.into_owned(),
))
}
})
}
}
#[cfg(any(
feature = "blocking-http-transport-reqwest",
feature = "blocking-http-transport-curl"
))]
impl SslVersion {
pub fn try_into_ssl_version(
&'static self,
value: std::borrow::Cow<'_, crate::bstr::BStr>,
) -> Result<git_protocol::transport::client::http::options::SslVersion, crate::config::ssl_version::Error>
{
use git_protocol::transport::client::http::options::SslVersion::*;
Ok(match value.as_ref().as_ref() {
b"default" | b"" => Default,
b"tlsv1" => TlsV1,
b"sslv2" => SslV2,
b"sslv3" => SslV3,
b"tlsv1.0" => TlsV1_0,
b"tlsv1.1" => TlsV1_1,
b"tlsv1.2" => TlsV1_2,
b"tlsv1.3" => TlsV1_3,
_ => return Err(crate::config::ssl_version::Error::from_value(self, value.into_owned())),
})
}
}
}
pub mod validate {
use std::error::Error;
use crate::{
bstr::{BStr, ByteSlice},
config::tree::keys::Validate,
};
pub struct SslVersion;
impl Validate for SslVersion {
fn validate(&self, _value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
#[cfg(any(
feature = "blocking-http-transport-reqwest",
feature = "blocking-http-transport-curl"
))]
super::Http::SSL_VERSION.try_into_ssl_version(std::borrow::Cow::Borrowed(_value))?;
Ok(())
}
}
pub struct ProxyAuthMethod;
impl Validate for ProxyAuthMethod {
fn validate(&self, _value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
#[cfg(any(
feature = "blocking-http-transport-reqwest",
feature = "blocking-http-transport-curl"
))]
super::Http::PROXY_AUTH_METHOD.try_into_proxy_auth_method(std::borrow::Cow::Borrowed(_value))?;
Ok(())
}
}
pub struct Version;
impl Validate for Version {
fn validate(&self, _value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
#[cfg(any(
feature = "blocking-http-transport-reqwest",
feature = "blocking-http-transport-curl"
))]
super::Http::VERSION.try_into_http_version(std::borrow::Cow::Borrowed(_value))?;
Ok(())
}
}
pub struct ExtraHeader;
impl Validate for ExtraHeader {
fn validate(&self, value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
value.to_str()?;
Ok(())
}
}
pub struct FollowRedirects;
impl Validate for FollowRedirects {
fn validate(&self, _value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
#[cfg(any(
feature = "blocking-http-transport-reqwest",
feature = "blocking-http-transport-curl"
))]
super::Http::FOLLOW_REDIRECTS.try_into_follow_redirects(std::borrow::Cow::Borrowed(_value), || {
git_config::Boolean::try_from(_value).map(|b| Some(b.0))
})?;
Ok(())
}
}
}