fix(client): omit default port from automatic Host headers (#2441)
Fixes hyperium/hyper#2407
This commit is contained in:
		| @@ -6,7 +6,7 @@ use std::time::Duration; | |||||||
| use futures_channel::oneshot; | use futures_channel::oneshot; | ||||||
| use futures_util::future::{self, Either, FutureExt as _, TryFutureExt as _}; | use futures_util::future::{self, Either, FutureExt as _, TryFutureExt as _}; | ||||||
| use http::header::{HeaderValue, HOST}; | use http::header::{HeaderValue, HOST}; | ||||||
| use http::uri::Scheme; | use http::uri::{Port, Scheme}; | ||||||
| use http::{Method, Request, Response, Uri, Version}; | use http::{Method, Request, Response, Uri, Version}; | ||||||
|  |  | ||||||
| use super::conn; | use super::conn; | ||||||
| @@ -231,7 +231,7 @@ where | |||||||
|                 let uri = req.uri().clone(); |                 let uri = req.uri().clone(); | ||||||
|                 req.headers_mut().entry(HOST).or_insert_with(|| { |                 req.headers_mut().entry(HOST).or_insert_with(|| { | ||||||
|                     let hostname = uri.host().expect("authority implies host"); |                     let hostname = uri.host().expect("authority implies host"); | ||||||
|                     if let Some(port) = uri.port() { |                     if let Some(port) = get_non_default_port(&uri) { | ||||||
|                         let s = format!("{}:{}", hostname, port); |                         let s = format!("{}:{}", hostname, port); | ||||||
|                         HeaderValue::from_str(&s) |                         HeaderValue::from_str(&s) | ||||||
|                     } else { |                     } else { | ||||||
| @@ -820,6 +820,20 @@ fn set_scheme(uri: &mut Uri, scheme: Scheme) { | |||||||
|     *uri = Uri::from_parts(parts).expect("scheme is valid"); |     *uri = Uri::from_parts(parts).expect("scheme is valid"); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | fn get_non_default_port(uri: &Uri) -> Option<Port<&str>> { | ||||||
|  |     match (uri.port().map(|p| p.as_u16()), is_schema_secure(uri)) { | ||||||
|  |         (Some(443), true) => None, | ||||||
|  |         (Some(80), false) => None, | ||||||
|  |         _ => uri.port(), | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fn is_schema_secure(uri: &Uri) -> bool { | ||||||
|  |     uri.scheme_str() | ||||||
|  |         .map(|scheme_str| matches!(scheme_str, "wss" | "https")) | ||||||
|  |         .unwrap_or_default() | ||||||
|  | } | ||||||
|  |  | ||||||
| /// A builder to configure a new [`Client`](Client). | /// A builder to configure a new [`Client`](Client). | ||||||
| /// | /// | ||||||
| /// # Example | /// # Example | ||||||
| @@ -1221,4 +1235,48 @@ mod unit_tests { | |||||||
|         assert_eq!(scheme, *"http"); |         assert_eq!(scheme, *"http"); | ||||||
|         assert_eq!(host, "hyper.rs"); |         assert_eq!(host, "hyper.rs"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     #[test] | ||||||
|  |     fn test_is_secure() { | ||||||
|  |         assert_eq!( | ||||||
|  |             is_schema_secure(&"http://hyper.rs".parse::<Uri>().unwrap()), | ||||||
|  |             false | ||||||
|  |         ); | ||||||
|  |         assert_eq!(is_schema_secure(&"hyper.rs".parse::<Uri>().unwrap()), false); | ||||||
|  |         assert_eq!( | ||||||
|  |             is_schema_secure(&"wss://hyper.rs".parse::<Uri>().unwrap()), | ||||||
|  |             true | ||||||
|  |         ); | ||||||
|  |         assert_eq!( | ||||||
|  |             is_schema_secure(&"ws://hyper.rs".parse::<Uri>().unwrap()), | ||||||
|  |             false | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     #[test] | ||||||
|  |     fn test_get_non_default_port() { | ||||||
|  |         assert!(get_non_default_port(&"http://hyper.rs".parse::<Uri>().unwrap()).is_none()); | ||||||
|  |         assert!(get_non_default_port(&"http://hyper.rs:80".parse::<Uri>().unwrap()).is_none()); | ||||||
|  |         assert!(get_non_default_port(&"https://hyper.rs:443".parse::<Uri>().unwrap()).is_none()); | ||||||
|  |         assert!(get_non_default_port(&"hyper.rs:80".parse::<Uri>().unwrap()).is_none()); | ||||||
|  |  | ||||||
|  |         assert_eq!( | ||||||
|  |             get_non_default_port(&"http://hyper.rs:123".parse::<Uri>().unwrap()) | ||||||
|  |                 .unwrap() | ||||||
|  |                 .as_u16(), | ||||||
|  |             123 | ||||||
|  |         ); | ||||||
|  |         assert_eq!( | ||||||
|  |             get_non_default_port(&"https://hyper.rs:80".parse::<Uri>().unwrap()) | ||||||
|  |                 .unwrap() | ||||||
|  |                 .as_u16(), | ||||||
|  |             80 | ||||||
|  |         ); | ||||||
|  |         assert_eq!( | ||||||
|  |             get_non_default_port(&"hyper.rs:123".parse::<Uri>().unwrap()) | ||||||
|  |                 .unwrap() | ||||||
|  |                 .as_u16(), | ||||||
|  |             123 | ||||||
|  |         ); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user