Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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 he [`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