Skip to content

Commit 0b11eee

Browse files
authored
fix(client): omit default port from automatic Host headers (#2441)
Fixes #2407
1 parent 6efc1a1 commit 0b11eee

File tree

1 file changed

+60
-2
lines changed

1 file changed

+60
-2
lines changed

src/client/client.rs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::time::Duration;
66
use futures_channel::oneshot;
77
use futures_util::future::{self, Either, FutureExt as _, TryFutureExt as _};
88
use http::header::{HeaderValue, HOST};
9-
use http::uri::Scheme;
9+
use http::uri::{Port, Scheme};
1010
use http::{Method, Request, Response, Uri, Version};
1111

1212
use super::conn;
@@ -231,7 +231,7 @@ where
231231
let uri = req.uri().clone();
232232
req.headers_mut().entry(HOST).or_insert_with(|| {
233233
let hostname = uri.host().expect("authority implies host");
234-
if let Some(port) = uri.port() {
234+
if let Some(port) = get_non_default_port(&uri) {
235235
let s = format!("{}:{}", hostname, port);
236236
HeaderValue::from_str(&s)
237237
} else {
@@ -820,6 +820,20 @@ fn set_scheme(uri: &mut Uri, scheme: Scheme) {
820820
*uri = Uri::from_parts(parts).expect("scheme is valid");
821821
}
822822

823+
fn get_non_default_port(uri: &Uri) -> Option<Port<&str>> {
824+
match (uri.port().map(|p| p.as_u16()), is_schema_secure(uri)) {
825+
(Some(443), true) => None,
826+
(Some(80), false) => None,
827+
_ => uri.port(),
828+
}
829+
}
830+
831+
fn is_schema_secure(uri: &Uri) -> bool {
832+
uri.scheme_str()
833+
.map(|scheme_str| matches!(scheme_str, "wss" | "https"))
834+
.unwrap_or_default()
835+
}
836+
823837
/// A builder to configure a new [`Client`](Client).
824838
///
825839
/// # Example
@@ -1221,4 +1235,48 @@ mod unit_tests {
12211235
assert_eq!(scheme, *"http");
12221236
assert_eq!(host, "hyper.rs");
12231237
}
1238+
1239+
#[test]
1240+
fn test_is_secure() {
1241+
assert_eq!(
1242+
is_schema_secure(&"http://hyper.rs".parse::<Uri>().unwrap()),
1243+
false
1244+
);
1245+
assert_eq!(is_schema_secure(&"hyper.rs".parse::<Uri>().unwrap()), false);
1246+
assert_eq!(
1247+
is_schema_secure(&"wss://hyper.rs".parse::<Uri>().unwrap()),
1248+
true
1249+
);
1250+
assert_eq!(
1251+
is_schema_secure(&"ws://hyper.rs".parse::<Uri>().unwrap()),
1252+
false
1253+
);
1254+
}
1255+
1256+
#[test]
1257+
fn test_get_non_default_port() {
1258+
assert!(get_non_default_port(&"http://hyper.rs".parse::<Uri>().unwrap()).is_none());
1259+
assert!(get_non_default_port(&"http://hyper.rs:80".parse::<Uri>().unwrap()).is_none());
1260+
assert!(get_non_default_port(&"https://hyper.rs:443".parse::<Uri>().unwrap()).is_none());
1261+
assert!(get_non_default_port(&"hyper.rs:80".parse::<Uri>().unwrap()).is_none());
1262+
1263+
assert_eq!(
1264+
get_non_default_port(&"http://hyper.rs:123".parse::<Uri>().unwrap())
1265+
.unwrap()
1266+
.as_u16(),
1267+
123
1268+
);
1269+
assert_eq!(
1270+
get_non_default_port(&"https://hyper.rs:80".parse::<Uri>().unwrap())
1271+
.unwrap()
1272+
.as_u16(),
1273+
80
1274+
);
1275+
assert_eq!(
1276+
get_non_default_port(&"hyper.rs:123".parse::<Uri>().unwrap())
1277+
.unwrap()
1278+
.as_u16(),
1279+
123
1280+
);
1281+
}
12241282
}

0 commit comments

Comments
 (0)