Skip to content

Commit

Permalink
refactor: reuse calls to try_old_curl macro
Browse files Browse the repository at this point in the history
At least doc duplicate can be eliminiated
  • Loading branch information
weihanglo committed Jun 10, 2023
1 parent cdd9649 commit 008501a
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 49 deletions.
32 changes: 4 additions & 28 deletions src/cargo/core/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ use std::time::{Duration, Instant};

use anyhow::Context;
use bytesize::ByteSize;
use curl::easy::{Easy, HttpVersion};
use curl::easy::Easy;
use curl::multi::{EasyHandle, Multi};
use lazycell::LazyCell;
use log::{debug, warn};
use log::debug;
use semver::Version;
use serde::Serialize;

Expand Down Expand Up @@ -725,32 +725,8 @@ impl<'a, 'cfg> Downloads<'a, 'cfg> {
handle.http_headers(headers)?;
}

// Enable HTTP/2 to be used as it'll allow true multiplexing which makes
// downloads much faster.
//
// Currently Cargo requests the `http2` feature of the `curl` crate
// which means it should always be built in. On OSX, however, we ship
// cargo still linked against the system libcurl. Building curl with
// ALPN support for HTTP/2 requires newer versions of OSX (the
// SecureTransport API) than we want to ship Cargo for. By linking Cargo
// against the system libcurl then older curl installations won't use
// HTTP/2 but newer ones will. All that to basically say we ignore
// errors here on OSX, but consider this a fatal error to not activate
// HTTP/2 on all other platforms.
if self.set.multiplexing {
crate::try_old_curl!(handle.http_version(HttpVersion::V2), "HTTP2");
} else {
handle.http_version(HttpVersion::V11)?;
}

// This is an option to `libcurl` which indicates that if there's a
// bunch of parallel requests to the same host they all wait until the
// pipelining status of the host is known. This means that we won't
// initiate dozens of connections to crates.io, but rather only one.
// Once the main one is opened we realized that pipelining is possible
// and multiplexing is possible with static.crates.io. All in all this
// reduces the number of connections down to a more manageable state.
crate::try_old_curl!(handle.pipewait(true), "pipewait");
// Enable HTTP/2 if possible.
crate::try_old_curl_http2_pipewait!(self.set.multiplexing, handle);

handle.write_function(move |buf| {
debug!("{} - {} bytes of data", token, buf.len());
Expand Down
21 changes: 4 additions & 17 deletions src/cargo/sources/registry/http_remote.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Access to a HTTP-based crate registry. See [`HttpRegistry`] for details.
use crate::core::{PackageId, SourceId};
use crate::ops::{self};
use crate::ops;
use crate::sources::registry::download;
use crate::sources::registry::MaybeLock;
use crate::sources::registry::{LoadResponse, RegistryConfig, RegistryData};
Expand All @@ -11,9 +11,9 @@ use crate::util::network::sleep::SleepTracker;
use crate::util::{auth, Config, Filesystem, IntoUrl, Progress, ProgressStyle};
use anyhow::Context;
use cargo_util::paths;
use curl::easy::{Easy, HttpVersion, List};
use curl::easy::{Easy, List};
use curl::multi::{EasyHandle, Multi};
use log::{debug, trace, warn};
use log::{debug, trace};
use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
use std::fs::{self, File};
Expand Down Expand Up @@ -618,20 +618,7 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> {
handle.follow_location(true)?;

// Enable HTTP/2 if possible.
if self.multiplexing {
crate::try_old_curl!(handle.http_version(HttpVersion::V2), "HTTP2");
} else {
handle.http_version(HttpVersion::V11)?;
}

// This is an option to `libcurl` which indicates that if there's a
// bunch of parallel requests to the same host they all wait until the
// pipelining status of the host is known. This means that we won't
// initiate dozens of connections to crates.io, but rather only one.
// Once the main one is opened we realized that pipelining is possible
// and multiplexing is possible with static.crates.io. All in all this
// reduces the number of connections done to a more manageable state.
crate::try_old_curl!(handle.pipewait(true), "pipewait");
crate::try_old_curl_http2_pipewait!(self.multiplexing, handle);

let mut headers = List::new();
// Include a header to identify the protocol. This allows the server to
Expand Down
39 changes: 35 additions & 4 deletions src/cargo/util/network/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,51 @@ impl<T> PollExt<T> for Poll<T> {
}
}

// When dynamically linked against libcurl, we want to ignore some failures
// when using old versions that don't support certain features.
/// When dynamically linked against libcurl, we want to ignore some failures
/// when using old versions that don't support certain features.
#[macro_export]
macro_rules! try_old_curl {
($e:expr, $msg:expr) => {
let result = $e;
if cfg!(target_os = "macos") {
if let Err(e) = result {
warn!("ignoring libcurl {} error: {}", $msg, e);
::log::warn!("ignoring libcurl {} error: {}", $msg, e);
}
} else {
use ::anyhow::Context;
result.with_context(|| {
anyhow::format_err!("failed to enable {}, is curl not built right?", $msg)
::anyhow::format_err!("failed to enable {}, is curl not built right?", $msg)
})?;
}
};
}

/// Enable HTTP/2 and pipewait to be used as it'll allow true multiplexing
/// which makes downloads much faster.
///
/// Currently Cargo requests the `http2` feature of the `curl` crate which
/// means it should always be built in. On OSX, however, we ship cargo still
/// linked against the system libcurl. Building curl with ALPN support for
/// HTTP/2 requires newer versions of OSX (the SecureTransport API) than we
/// want to ship Cargo for. By linking Cargo against the system libcurl then
/// older curl installations won't use HTTP/2 but newer ones will. All that to
/// basically say we ignore errors here on OSX, but consider this a fatal error
/// to not activate HTTP/2 on all other platforms.
///
/// `pipewait` is an option which indicates that if there's a bunch of parallel
/// requests to the same host they all wait until the pipelining status of the
/// host is known. This means that we won't initiate dozens of connections but
/// rather only one. Once the main one is opened we realized that pipelining is
/// possible and multiplexing is possible. All in all this reduces the number
/// of connections down to a more manageable state.
#[macro_export]
macro_rules! try_old_curl_http2_pipewait {
($multiplexing:expr, $handle:expr) => {
if $multiplexing {
$crate::try_old_curl!($handle.http_version(curl::easy::HttpVersion::V2), "HTTP/2");
} else {
$handle.http_version(curl::easy::HttpVersion::V11)?;
}
$crate::try_old_curl!($handle.pipewait(true), "pipewait");
};
}

0 comments on commit 008501a

Please sign in to comment.