Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ encoding_rs = { version = "0.8", optional = true }
http-body = "1"
http-body-util = "0.1"
hyper = { version = "1.1", features = ["http1", "client"] }
hyper-util = { version = "0.1.10", features = ["http1", "client", "client-legacy", "tokio"] }
hyper-util = { version = "0.1.11", features = ["http1", "client", "client-legacy", "tokio"] }
h2 = { version = "0.4", optional = true }
once_cell = "1.18"
log = "0.4.17"
Expand Down
113 changes: 104 additions & 9 deletions src/async_impl/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,18 @@ struct Config {
#[cfg(feature = "http2")]
http2_keep_alive_while_idle: bool,
local_address: Option<IpAddr>,
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
interface: Option<String>,
nodelay: bool,
#[cfg(feature = "cookies")]
Expand Down Expand Up @@ -262,7 +273,18 @@ impl ClientBuilder {
#[cfg(feature = "http2")]
http2_keep_alive_while_idle: false,
local_address: None,
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
interface: None,
nodelay: true,
hickory_dns: cfg!(feature = "hickory-dns"),
Expand Down Expand Up @@ -462,7 +484,14 @@ impl ClientBuilder {
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "linux"
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
config.interface.as_deref(),
config.nodelay,
Expand Down Expand Up @@ -506,7 +535,14 @@ impl ClientBuilder {
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "linux"
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
config.interface.as_deref(),
config.nodelay,
Expand Down Expand Up @@ -701,7 +737,14 @@ impl ClientBuilder {
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "linux"
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
config.interface.as_deref(),
config.nodelay,
Expand All @@ -721,7 +764,18 @@ impl ClientBuilder {
http,
proxies.clone(),
config.local_address,
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
config.interface.as_deref(),
config.nodelay,
)
Expand Down Expand Up @@ -1403,7 +1457,23 @@ impl ClientBuilder {
self
}

/// Bind to an interface by `SO_BINDTODEVICE`.
/// Bind connections only on the specified network interface.
///
/// This option is only available on the following operating systems:
///
/// - Android
/// - Fuchsia
/// - Linux,
/// - macOS and macOS-like systems (iOS, tvOS, watchOS and visionOS)
/// - Solaris and illumos
///
/// On Android, Linux, and Fuchsia, this uses the
/// [`SO_BINDTODEVICE`][man-7-socket] socket option. On macOS and macOS-like
/// systems, Solaris, and illumos, this instead uses the [`IP_BOUND_IF` and
/// `IPV6_BOUND_IF`][man-7p-ip] socket options (as appropriate).
///
/// Note that connections will fail if the provided interface name is not a
/// network interface that currently exists when a connection is established.
///
/// # Example
///
Expand All @@ -1415,7 +1485,21 @@ impl ClientBuilder {
/// .interface(interface)
/// .build().unwrap();
/// ```
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
///
/// [man-7-socket]: https://man7.org/linux/man-pages/man7/socket.7.html
/// [man-7p-ip]: https://docs.oracle.com/cd/E86824_01/html/E54777/ip-7p.html
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
pub fn interface(mut self, interface: &str) -> ClientBuilder {
self.config.interface = Some(interface.to_string());
self
Expand Down Expand Up @@ -2355,7 +2439,18 @@ impl Config {
f.field("local_address", v);
}

#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
if let Some(ref v) = self.interface {
f.field("interface", v);
}
Expand Down
104 changes: 96 additions & 8 deletions src/connect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,15 +148,37 @@ where {
mut http: HttpConnector,
proxies: Arc<Vec<Proxy>>,
local_addr: T,
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
interface: Option<&str>,
nodelay: bool,
) -> ConnectorBuilder
where
T: Into<Option<IpAddr>>,
{
http.set_local_address(local_addr.into());
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
if let Some(interface) = interface {
http.set_interface(interface.to_owned());
}
Expand All @@ -177,7 +199,18 @@ where {
proxies: Arc<Vec<Proxy>>,
user_agent: Option<HeaderValue>,
local_addr: T,
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
interface: Option<&str>,
nodelay: bool,
tls_info: bool,
Expand All @@ -192,7 +225,18 @@ where {
proxies,
user_agent,
local_addr,
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
interface,
nodelay,
tls_info,
Expand All @@ -206,7 +250,18 @@ where {
proxies: Arc<Vec<Proxy>>,
user_agent: Option<HeaderValue>,
local_addr: T,
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
interface: Option<&str>,
nodelay: bool,
tls_info: bool,
Expand All @@ -215,7 +270,18 @@ where {
T: Into<Option<IpAddr>>,
{
http.set_local_address(local_addr.into());
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
if let Some(interface) = interface {
http.set_interface(interface);
}
Expand All @@ -240,7 +306,18 @@ where {
proxies: Arc<Vec<Proxy>>,
user_agent: Option<HeaderValue>,
local_addr: T,
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
interface: Option<&str>,
nodelay: bool,
tls_info: bool,
Expand All @@ -249,7 +326,18 @@ where {
T: Into<Option<IpAddr>>,
{
http.set_local_address(local_addr.into());
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "illumos",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "solaris",
target_os = "tvos",
target_os = "visionos",
target_os = "watchos",
))]
if let Some(interface) = interface {
http.set_interface(interface.to_owned());
}
Expand Down
Loading