Skip to content

Commit

Permalink
feat(client): use non-zero ports resolved by dns resolvers (#148)
Browse files Browse the repository at this point in the history
If a resolved address sets the port number to something besides `0`, and the port isn't otherwise explicitly asked for, the `HttpConnector` will now use that port. This allows custom resolvers that might lookup SRVB or HTTPSrr records that include a port number.

cc seanmonstar/reqwest#2413
  • Loading branch information
Nuhvi authored Sep 17, 2024
1 parent 4a8a261 commit 2639193
Showing 1 changed file with 32 additions and 1 deletion.
33 changes: 32 additions & 1 deletion src/client/legacy/connect/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,8 @@ where
.map_err(ConnectError::dns)?;
let addrs = addrs
.map(|mut addr| {
addr.set_port(port);
set_port(&mut addr, port, dst.port().is_some());

addr
})
.collect();
Expand Down Expand Up @@ -825,9 +826,19 @@ impl ConnectingTcp<'_> {
}
}

/// Respect explicit ports in the URI, if none, either
/// keep non `0` ports resolved from a custom dns resolver,
/// or use the default port for the scheme.
fn set_port(addr: &mut SocketAddr, host_port: u16, explicit: bool) {
if explicit || addr.port() == 0 {
addr.set_port(host_port)
};
}

#[cfg(test)]
mod tests {
use std::io;
use std::net::SocketAddr;

use ::http::Uri;

Expand All @@ -836,6 +847,8 @@ mod tests {
use super::super::sealed::{Connect, ConnectSvc};
use super::{Config, ConnectError, HttpConnector};

use super::set_port;

async fn connect<C>(
connector: C,
dst: Uri,
Expand Down Expand Up @@ -1234,4 +1247,22 @@ mod tests {
panic!("test failed");
}
}

#[test]
fn test_set_port() {
// Respect explicit ports no matter what the resolved port is.
let mut addr = SocketAddr::from(([0, 0, 0, 0], 6881));
set_port(&mut addr, 42, true);
assert_eq!(addr.port(), 42);

// Ignore default host port, and use the socket port instead.
let mut addr = SocketAddr::from(([0, 0, 0, 0], 6881));
set_port(&mut addr, 443, false);
assert_eq!(addr.port(), 6881);

// Use the default port if the resolved port is `0`.
let mut addr = SocketAddr::from(([0, 0, 0, 0], 0));
set_port(&mut addr, 443, false);
assert_eq!(addr.port(), 443);
}
}

0 comments on commit 2639193

Please sign in to comment.