Skip to content

Commit

Permalink
feat(client): add Config::set_host option
Browse files Browse the repository at this point in the history
If set to false, the `Client` will no longer automatically set the
`Host` header if absent.
  • Loading branch information
seanmonstar committed Mar 6, 2018
1 parent 3e87eb4 commit 33a385c
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 2 deletions.
22 changes: 21 additions & 1 deletion src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pub struct Client<C, B = proto::Body> {
h1_writev: bool,
pool: Pool<HyperClient<B>>,
retry_canceled_requests: bool,
set_host: bool,
}

impl Client<HttpConnector, proto::Body> {
Expand Down Expand Up @@ -101,6 +102,7 @@ impl<C, B> Client<C, B> {
h1_writev: config.h1_writev,
pool: Pool::new(config.keep_alive, config.keep_alive_timeout),
retry_canceled_requests: config.retry_canceled_requests,
set_host: config.set_host,
}
}
}
Expand Down Expand Up @@ -147,7 +149,7 @@ where C: Connect,
))));
}
};
if !req.headers().has::<Host>() {
if self.set_host && !req.headers().has::<Host>() {
let host = Host::new(
domain.host().expect("authority implies host").to_owned(),
domain.port(),
Expand Down Expand Up @@ -289,6 +291,7 @@ impl<C, B> Clone for Client<C, B> {
h1_writev: self.h1_writev,
pool: self.pool.clone(),
retry_canceled_requests: self.retry_canceled_requests,
set_host: self.set_host,
}
}
}
Expand Down Expand Up @@ -413,6 +416,7 @@ pub struct Config<C, B> {
//TODO: make use of max_idle config
max_idle: usize,
retry_canceled_requests: bool,
set_host: bool,
}

/// Phantom type used to signal that `Config` should create a `HttpConnector`.
Expand All @@ -429,6 +433,7 @@ impl Default for Config<UseDefaultConnector, proto::Body> {
h1_writev: true,
max_idle: 5,
retry_canceled_requests: true,
set_host: true,
}
}
}
Expand All @@ -453,6 +458,7 @@ impl<C, B> Config<C, B> {
h1_writev: self.h1_writev,
max_idle: self.max_idle,
retry_canceled_requests: self.retry_canceled_requests,
set_host: self.set_host,
}
}

Expand All @@ -467,6 +473,7 @@ impl<C, B> Config<C, B> {
h1_writev: self.h1_writev,
max_idle: self.max_idle,
retry_canceled_requests: self.retry_canceled_requests,
set_host: self.set_host,
}
}

Expand Down Expand Up @@ -521,6 +528,18 @@ impl<C, B> Config<C, B> {
self
}

/// Set whether to automatically add the `Host` header to requests.
///
/// If true, and a request does not include a `Host` header, one will be
/// added automatically, derived from the authority of the `Uri`.
///
/// Default is `true`.
#[inline]
pub fn set_host(mut self, val: bool) -> Config<C, B> {
self.set_host = val;
self
}

#[doc(hidden)]
#[deprecated(since="0.11.11", note="no_proto is always enabled")]
pub fn no_proto(self) -> Config<C, B> {
Expand Down Expand Up @@ -573,6 +592,7 @@ impl<C, B> fmt::Debug for Config<C, B> {
.field("keep_alive_timeout", &self.keep_alive_timeout)
.field("http1_writev", &self.h1_writev)
.field("max_idle", &self.max_idle)
.field("set_host", &self.set_host)
.finish()
}
}
Expand Down
78 changes: 77 additions & 1 deletion tests/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,45 @@ macro_rules! test {
headers: [ $($response_headers:expr,)* ],
body: $response_body:expr,
) => (
test! {
name: $name,
server:
expected: $server_expected,
reply: $server_reply,
client:
set_host: true,
request:
method: $client_method,
url: $client_url,
headers: [ $($request_headers,)* ],
body: $request_body,
proxy: $request_proxy,

response:
status: $client_status,
headers: [ $($response_headers,)* ],
body: $response_body,
}
);
(
name: $name:ident,
server:
expected: $server_expected:expr,
reply: $server_reply:expr,
client:
set_host: $set_host:expr,
request:
method: $client_method:ident,
url: $client_url:expr,
headers: [ $($request_headers:expr,)* ],
body: $request_body:expr,
proxy: $request_proxy:expr,

response:
status: $client_status:ident,
headers: [ $($response_headers:expr,)* ],
body: $response_body:expr,
) => (
#[test]
fn $name() {
#![allow(unused)]
Expand All @@ -60,6 +99,7 @@ macro_rules! test {
expected: $server_expected,
reply: $server_reply,
client:
set_host: $set_host,
request:
method: $client_method,
url: $client_url,
Expand Down Expand Up @@ -111,6 +151,7 @@ macro_rules! test {
expected: $server_expected,
reply: $server_reply,
client:
set_host: true,
request:
method: $client_method,
url: $client_url,
Expand All @@ -132,6 +173,7 @@ macro_rules! test {
expected: $server_expected:expr,
reply: $server_reply:expr,
client:
set_host: $set_host:expr,
request:
method: $client_method:ident,
url: $client_url:expr,
Expand All @@ -142,7 +184,12 @@ macro_rules! test {
let server = TcpListener::bind("127.0.0.1:0").unwrap();
let addr = server.local_addr().unwrap();
let mut core = $core;
let client = client(&core.handle());

let mut config = Client::configure();
if !$set_host {
config = config.set_host(false);
}
let client = config.build(&core.handle());
let mut req = Request::new(Method::$client_method, format!($client_url, addr=addr).parse().unwrap());
$(
req.headers_mut().set($request_headers);
Expand Down Expand Up @@ -545,6 +592,35 @@ test! {

}

test! {
name: client_set_host_false,

server:
// {addr} is here because format! requires it to exist in the string
expected: "\
GET /no-host/{addr} HTTP/1.1\r\n\
\r\n\
",
reply: "\
HTTP/1.1 200 OK\r\n\
Content-Length: 0\r\n\
\r\n\
",

client:
set_host: false,
request:
method: Get,
url: "http://{addr}/no-host/{addr}",
headers: [],
body: None,
proxy: false,
response:
status: Ok,
headers: [],
body: None,
}

#[test]
fn client_keep_alive() {
let server = TcpListener::bind("127.0.0.1:0").unwrap();
Expand Down

0 comments on commit 33a385c

Please sign in to comment.