Skip to content

Commit

Permalink
feat: Allow binding interface (#2163)
Browse files Browse the repository at this point in the history
  • Loading branch information
yujincheng08 authored and seanmonstar committed Mar 20, 2024
1 parent fee78ec commit 18f2bb8
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 1 deletion.
51 changes: 51 additions & 0 deletions src/async_impl/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ 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"))]
interface: Option<String>,
nodelay: bool,
#[cfg(feature = "cookies")]
cookie_store: Option<Arc<dyn cookie::CookieStore>>,
Expand Down Expand Up @@ -234,6 +236,8 @@ 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"))]
interface: None,
nodelay: true,
hickory_dns: cfg!(feature = "hickory-dns"),
#[cfg(feature = "cookies")]
Expand Down Expand Up @@ -430,6 +434,12 @@ impl ClientBuilder {
proxies.clone(),
user_agent(&config.headers),
config.local_address,
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "linux"
))]
config.interface.as_deref(),
config.nodelay,
config.tls_info,
)?
Expand All @@ -441,6 +451,8 @@ impl ClientBuilder {
proxies.clone(),
user_agent(&config.headers),
config.local_address,
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
config.interface.as_deref(),
config.nodelay,
config.tls_info,
),
Expand All @@ -456,6 +468,12 @@ impl ClientBuilder {
config.quic_receive_window,
config.quic_send_window,
config.local_address,
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "linux"
))]
config.interface.as_deref(),
&config.http_version_pref,
)?;
}
Expand All @@ -466,6 +484,12 @@ impl ClientBuilder {
proxies.clone(),
user_agent(&config.headers),
config.local_address,
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "linux"
))]
config.interface.as_deref(),
config.nodelay,
config.tls_info,
)
Expand Down Expand Up @@ -592,6 +616,12 @@ impl ClientBuilder {
proxies.clone(),
user_agent(&config.headers),
config.local_address,
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
target_os = "linux"
))]
config.interface.as_deref(),
config.nodelay,
config.tls_info,
)
Expand Down Expand Up @@ -1237,6 +1267,22 @@ impl ClientBuilder {
self
}

/// Bind to an interface by `SO_BINDTODEVICE`.
///
/// # Example
///
/// ```
/// let interface = "lo";
/// let client = reqwest::Client::builder()
/// .interface(interface)
/// .build().unwrap();
/// ```
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
pub fn interface(mut self, interface: &str) -> ClientBuilder {
self.config.interface = Some(interface.to_string());
self
}

/// Set that all sockets have `SO_KEEPALIVE` set with the supplied duration.
///
/// If `None`, the option will not be set.
Expand Down Expand Up @@ -2062,6 +2108,11 @@ impl Config {
f.field("local_address", v);
}

#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
if let Some(ref v) = self.interface {
f.field("interface", v);
}

if self.nodelay {
f.field("tcp_nodelay", &true);
}
Expand Down
15 changes: 15 additions & 0 deletions src/blocking/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,21 @@ impl ClientBuilder {
self.with_inner(move |inner| inner.local_address(addr))
}

/// Bind to an interface by `SO_BINDTODEVICE`.
///
/// # Example
///
/// ```
/// let interface = "lo";
/// let client = reqwest::blocking::Client::builder()
/// .interface(interface)
/// .build().unwrap();
/// ```
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
pub fn interface(self, interface: &str) -> ClientBuilder {
self.with_inner(move |inner| inner.interface(interface))
}

/// Set that all sockets have `SO_KEEPALIVE` set with the supplied duration.
///
/// If `None`, the option will not be set.
Expand Down
24 changes: 23 additions & 1 deletion src/connect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ impl Connector {
proxies: Arc<Vec<Proxy>>,
user_agent: Option<HeaderValue>,
local_addr: T,
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
interface: Option<&str>,
nodelay: bool,
tls_info: bool,
) -> crate::Result<Connector>
Expand All @@ -94,7 +96,15 @@ impl Connector {
{
let tls = tls.build().map_err(crate::error::builder)?;
Ok(Self::from_built_default_tls(
http, tls, proxies, user_agent, local_addr, nodelay, tls_info,
http,
tls,
proxies,
user_agent,
local_addr,
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
interface,
nodelay,
tls_info,
))
}

Expand All @@ -105,13 +115,19 @@ impl Connector {
proxies: Arc<Vec<Proxy>>,
user_agent: Option<HeaderValue>,
local_addr: T,
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
interface: Option<&str>,
nodelay: bool,
tls_info: bool,
) -> Connector
where
T: Into<Option<IpAddr>>,
{
http.set_local_address(local_addr.into());
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
if let Some(interface) = interface {
http.set_interface(interface);
}
http.set_nodelay(nodelay);
http.enforce_http(false);

Expand All @@ -133,13 +149,19 @@ impl Connector {
proxies: Arc<Vec<Proxy>>,
user_agent: Option<HeaderValue>,
local_addr: T,
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
interface: Option<&str>,
nodelay: bool,
tls_info: bool,
) -> Connector
where
T: Into<Option<IpAddr>>,
{
http.set_local_address(local_addr.into());
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
if let Some(interface) = interface {
http.set_interface(interface.to_owned());
}
http.set_nodelay(nodelay);
http.enforce_http(false);

Expand Down

0 comments on commit 18f2bb8

Please sign in to comment.