Skip to content

Commit 2357bb0

Browse files
committed
Centralize HTTP configuration in one struct
Gives us one nice place to access and document all HTTP-related configuration
1 parent 5bba426 commit 2357bb0

File tree

5 files changed

+64
-41
lines changed

5 files changed

+64
-41
lines changed

src/cargo/core/package.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,7 @@ impl<'cfg> PackageSet<'cfg> {
376376
// that it's buggy, and we've empirically seen that it's buggy with HTTP
377377
// proxies.
378378
let mut multi = Multi::new();
379-
let multiplexing = config
380-
.get::<Option<bool>>("http.multiplexing")?
381-
.unwrap_or(true);
379+
let multiplexing = config.http_config()?.multiplexing.unwrap_or(true);
382380
multi
383381
.pipelining(false, multiplexing)
384382
.chain_err(|| "failed to enable multiplexing/pipelining in curl")?;

src/cargo/ops/registry.rs

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -408,34 +408,26 @@ pub fn http_handle_and_timeout(config: &Config) -> CargoResult<(Easy, HttpTimeou
408408
}
409409

410410
pub fn needs_custom_http_transport(config: &Config) -> CargoResult<bool> {
411-
let proxy_exists = http_proxy_exists(config)?;
412-
let timeout = HttpTimeout::new(config)?.is_non_default();
413-
let cainfo = config.get_path("http.cainfo")?;
414-
let check_revoke = config.get_bool("http.check-revoke")?;
415-
let user_agent = config.get_string("http.user-agent")?;
416-
let ssl_version = config.get::<Option<SslVersionConfig>>("http.ssl-version")?;
417-
418-
Ok(proxy_exists
419-
|| timeout
420-
|| cainfo.is_some()
421-
|| check_revoke.is_some()
422-
|| user_agent.is_some()
423-
|| ssl_version.is_some())
411+
Ok(http_proxy_exists(config)?
412+
|| *config.http_config()? != Default::default()
413+
|| env::var_os("HTTP_TIMEOUT").is_some())
424414
}
425415

426416
/// Configure a libcurl http handle with the defaults options for Cargo
427417
pub fn configure_http_handle(config: &Config, handle: &mut Easy) -> CargoResult<HttpTimeout> {
418+
let http = config.http_config()?;
428419
if let Some(proxy) = http_proxy(config)? {
429420
handle.proxy(&proxy)?;
430421
}
431-
if let Some(cainfo) = config.get_path("http.cainfo")? {
432-
handle.cainfo(&cainfo.val)?;
422+
if let Some(cainfo) = http.cainfo.clone() {
423+
let cainfo = cainfo.resolve(config);
424+
handle.cainfo(&cainfo)?;
433425
}
434-
if let Some(check) = config.get_bool("http.check-revoke")? {
435-
handle.ssl_options(SslOpt::new().no_revoke(!check.val))?;
426+
if let Some(check) = http.check_revoke {
427+
handle.ssl_options(SslOpt::new().no_revoke(!check))?;
436428
}
437-
if let Some(user_agent) = config.get_string("http.user-agent")? {
438-
handle.useragent(&user_agent.val)?;
429+
if let Some(user_agent) = &http.user_agent {
430+
handle.useragent(user_agent)?;
439431
} else {
440432
handle.useragent(&version().to_string())?;
441433
}
@@ -456,7 +448,7 @@ pub fn configure_http_handle(config: &Config, handle: &mut Easy) -> CargoResult<
456448
};
457449
Ok(version)
458450
}
459-
if let Some(ssl_version) = config.get::<Option<SslVersionConfig>>("http.ssl-version")? {
451+
if let Some(ssl_version) = &http_config.ssl_version {
460452
match ssl_version {
461453
SslVersionConfig::Single(s) => {
462454
let version = to_ssl_version(s.as_str())?;
@@ -472,7 +464,7 @@ pub fn configure_http_handle(config: &Config, handle: &mut Easy) -> CargoResult<
472464
}
473465
}
474466

475-
if let Some(true) = config.get::<Option<bool>>("http.debug")? {
467+
if let Some(true) = http.debug {
476468
handle.verbose(true)?;
477469
handle.debug_function(|kind, data| {
478470
let (prefix, level) = match kind {
@@ -513,11 +505,10 @@ pub struct HttpTimeout {
513505

514506
impl HttpTimeout {
515507
pub fn new(config: &Config) -> CargoResult<HttpTimeout> {
516-
let low_speed_limit = config
517-
.get::<Option<u32>>("http.low-speed-limit")?
518-
.unwrap_or(10);
508+
let config = config.http_config()?;
509+
let low_speed_limit = config.low_speed_limit.unwrap_or(10);
519510
let seconds = config
520-
.get::<Option<u64>>("http.timeout")?
511+
.timeout
521512
.or_else(|| env::var("HTTP_TIMEOUT").ok().and_then(|s| s.parse().ok()))
522513
.unwrap_or(30);
523514
Ok(HttpTimeout {
@@ -526,10 +517,6 @@ impl HttpTimeout {
526517
})
527518
}
528519

529-
fn is_non_default(&self) -> bool {
530-
self.dur != Duration::new(30, 0) || self.low_speed_limit != 10
531-
}
532-
533520
pub fn configure(&self, handle: &mut Easy) -> CargoResult<()> {
534521
// The timeout option for libcurl by default times out the entire
535522
// transfer, but we probably don't want this. Instead we only set
@@ -548,8 +535,9 @@ impl HttpTimeout {
548535
/// Favor cargo's `http.proxy`, then git's `http.proxy`. Proxies specified
549536
/// via environment variables are picked up by libcurl.
550537
fn http_proxy(config: &Config) -> CargoResult<Option<String>> {
551-
if let Some(s) = config.get_string("http.proxy")? {
552-
return Ok(Some(s.val));
538+
let http = config.http_config()?;
539+
if let Some(s) = &http.proxy {
540+
return Ok(Some(s.clone()));
553541
}
554542
if let Ok(cfg) = git2::Config::open_default() {
555543
if let Ok(s) = cfg.get_str("http.proxy") {

src/cargo/util/config/mod.rs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ pub struct Config {
9494
/// Lock, if held, of the global package cache along with the number of
9595
/// acquisitions so far.
9696
package_cache_lock: RefCell<Option<(Option<FileLock>, usize)>>,
97+
/// HTTP configuration for Cargo
98+
http_config: LazyCell<CargoHttpConfig>,
9799
}
98100

99101
impl Config {
@@ -152,6 +154,7 @@ impl Config {
152154
profiles: LazyCell::new(),
153155
updated_sources: LazyCell::new(),
154156
package_cache_lock: RefCell::new(None),
157+
http_config: LazyCell::new(),
155158
}
156159
}
157160

@@ -916,6 +919,11 @@ impl Config {
916919
Ok(http)
917920
}
918921

922+
pub fn http_config(&self) -> CargoResult<&CargoHttpConfig> {
923+
self.http_config
924+
.try_borrow_with(|| Ok(self.get::<CargoHttpConfig>("http")?))
925+
}
926+
919927
pub fn crates_io_source_id<F>(&self, f: F) -> CargoResult<SourceId>
920928
where
921929
F: FnMut() -> CargoResult<SourceId>,
@@ -1402,6 +1410,29 @@ pub fn clippy_driver() -> PathBuf {
14021410
.into()
14031411
}
14041412

1413+
#[derive(Clone, Debug, Deserialize)]
1414+
pub struct SslVersionConfigRange {
1415+
pub min: Option<String>,
1416+
pub max: Option<String>,
1417+
}
1418+
1419+
#[derive(Debug, Default, Deserialize, PartialEq)]
1420+
pub struct CargoHttpConfig {
1421+
pub proxy: Option<String>,
1422+
#[serde(rename = "low-speed-limit")]
1423+
pub low_speed_limit: Option<u32>,
1424+
pub timeout: Option<u64>,
1425+
pub cainfo: Option<ConfigRelativePath>,
1426+
#[serde(rename = "check-revoke")]
1427+
pub check_revoke: Option<bool>,
1428+
#[serde(rename = "user-agent")]
1429+
pub user_agent: Option<String>,
1430+
pub debug: Option<bool>,
1431+
pub multiplexing: Option<bool>,
1432+
#[serde(rename = "ssl-version")]
1433+
pub ssl_version: Option<SslVersionConfig>,
1434+
}
1435+
14051436
/// Configuration for `ssl-version` in `http` section
14061437
/// There are two ways to configure:
14071438
///
@@ -1421,9 +1452,3 @@ pub enum SslVersionConfig {
14211452
Single(String),
14221453
Range(SslVersionConfigRange),
14231454
}
1424-
1425-
#[derive(Clone, Debug, Deserialize)]
1426-
pub struct SslVersionConfigRange {
1427-
pub min: Option<String>,
1428-
pub max: Option<String>,
1429-
}

src/cargo/util/config/path.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::path::PathBuf;
55
/// Use with the `get` API to fetch a string that will be converted to a
66
/// `PathBuf`. Relative paths are converted to absolute paths based on the
77
/// location of the config file.
8-
#[derive(Deserialize)]
8+
#[derive(Debug, Deserialize, PartialEq, Clone)]
99
#[serde(transparent)]
1010
pub struct ConfigRelativePath(Value<String>);
1111

src/cargo/util/config/value.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ use crate::util::config::Config;
22
use serde::de;
33
use std::fmt;
44
use std::marker;
5+
use std::mem;
56
use std::path::{Path, PathBuf};
67

8+
#[derive(Debug, PartialEq, Clone)]
79
pub struct Value<T> {
810
pub val: T,
911
pub definition: Definition,
@@ -31,6 +33,16 @@ impl Definition {
3133
}
3234
}
3335

36+
impl PartialEq for Definition {
37+
fn eq(&self, other: &Definition) -> bool {
38+
// configuration values are equivalent no matter where they're defined,
39+
// but they need to be defined in the same location. For example if
40+
// they're defined in the environment that's different than being
41+
// defined in a file due to path interepretations.
42+
mem::discriminant(self) == mem::discriminant(other)
43+
}
44+
}
45+
3446
impl fmt::Display for Definition {
3547
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3648
match self {

0 commit comments

Comments
 (0)