#
cargo/util/network/
mod.rs

    1//! Utilities for networking.
    2
    3use std::net::Ipv4Addr;
    4use std::net::Ipv6Addr;
    5use std::net::SocketAddr;
    6use std::net::SocketAddrV4;
    7use std::net::SocketAddrV6;
    8use std::task::Poll;
    9
    10pub mod http;
    11pub mod proxy;
    12pub mod retry;
    13pub mod sleep;
    14
    15/// LOCALHOST constants for both IPv4 and IPv6.
    16pub const LOCALHOST: [SocketAddr; 2] = [
    17    SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0)),
    18    SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::LOCALHOST, 0, 0, 0)),
    19];
    20
    21pub trait PollExt<T> {
    22    fn expect(self, msg: &str) -> T;
    23}
    24
    25impl<T> PollExt<T> for Poll<T> {
    26    #[track_caller]
    27    fn expect(self, msg: &str) -> T {
    28        match self {
    29            Poll::Ready(val) => val,
    30            Poll::Pending => panic!("{}", msg),
    31        }
    32    }
    33}
    34
    35/// When dynamically linked against libcurl, we want to ignore some failures
    36/// when using old versions that don't support certain features.
    37#[macro_export]
    38macro_rules! try_old_curl {
    39    ($e:expr, $msg:expr) => {
    40        let result = $e;
    41        if cfg!(target_os = "macos") {
    42            if let Err(e) = result {
    43                ::tracing::warn!(target: "network", "ignoring libcurl {} error: {}", $msg, e);
    44            }
    45        } else {
    46            use ::anyhow::Context;
    47            result.with_context(|| {
    48                ::anyhow::format_err!("failed to enable {}, is curl not built right?", $msg)
    49            })?;
    50        }
    51    };
    52}
    53
    54/// Enable HTTP/2 and pipewait to be used as it'll allow true multiplexing
    55/// which makes downloads much faster.
    56///
    57/// Currently Cargo requests the `http2` feature of the `curl` crate which
    58/// means it should always be built in. On OSX, however, we ship cargo still
    59/// linked against the system libcurl. Building curl with ALPN support for
    60/// HTTP/2 requires newer versions of OSX (the SecureTransport API) than we
    61/// want to ship Cargo for. By linking Cargo against the system libcurl then
    62/// older curl installations won't use HTTP/2 but newer ones will. All that to
    63/// basically say we ignore errors here on OSX, but consider this a fatal error
    64/// to not activate HTTP/2 on all other platforms.
    65///
    66/// `pipewait` is an option which indicates that if there's a bunch of parallel
    67/// requests to the same host they all wait until the pipelining status of the
    68/// host is known. This means that we won't initiate dozens of connections but
    69/// rather only one. Once the main one is opened we realized that pipelining is
    70/// possible and multiplexing is possible. All in all this reduces the number
    71/// of connections down to a more manageable state.
    72#[macro_export]
    73macro_rules! try_old_curl_http2_pipewait {
    74    ($multiplexing:expr, $handle:expr) => {
    75        if $multiplexing {
    76            $crate::try_old_curl!($handle.http_version(curl::easy::HttpVersion::V2), "HTTP/2");
    77        } else {
    78            $handle.http_version(curl::easy::HttpVersion::V11)?;
    79        }
    80        $crate::try_old_curl!($handle.pipewait(true), "pipewait");
    81    };
    82}