diff --git a/src/request.rs b/src/request.rs index 5951dcb..9f5abb3 100644 --- a/src/request.rs +++ b/src/request.rs @@ -1,5 +1,6 @@ use std::io::Read; use std::{fmt, time}; +use std::borrow::Cow; use url::{form_urlencoded, ParseError, Url}; @@ -32,6 +33,7 @@ pub struct Request { url: String, pub(crate) headers: Vec
, timeout: Option, + spoofed_host: Option>, } impl fmt::Debug for Request { @@ -52,6 +54,7 @@ impl Request { url, headers: vec![], timeout: None, + spoofed_host: None, } } @@ -62,6 +65,13 @@ impl Request { self } + #[inline(always)] + /// Sets overall timeout for the request, overriding agent's configuration if any. + pub fn connection_host(mut self, dns_host: Cow<'static, str>) -> Self { + self.spoofed_host = Some(dns_host); + self + } + /// Sends the request with no body and blocks the caller until done. /// /// Use this with GET, HEAD, OPTIONS or TRACE. It sends neither @@ -138,7 +148,7 @@ impl Request { let request_fn = |req: Request| { let reader = payload.into_read(); - let unit = Unit::new( + let mut unit = Unit::new( &req.agent, &req.method, &url, @@ -147,6 +157,9 @@ impl Request { deadline, ); + // forward the spoofed host address + unit.spoofed_host = req.spoofed_host; + unit::connect(unit, true, reader).map_err(|e| e.url(url.clone())) }; diff --git a/src/unit.rs b/src/unit.rs index 13c3c9a..15dc600 100644 --- a/src/unit.rs +++ b/src/unit.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::fmt::{self, Display}; use std::io::{self, Write}; use std::ops::Range; @@ -32,6 +33,7 @@ pub(crate) struct Unit { is_chunked: bool, headers: Vec
, pub deadline: Option, + pub spoofed_host: Option>, } impl Unit { @@ -252,8 +254,13 @@ fn connect_inner( .unwrap(); let url = &unit.url; let method = &unit.method; + + let socket_host = unit.spoofed_host + .map(|r|r.as_ref()) + .unwrap_or(host); + // open socket - let (mut stream, is_recycled) = connect_socket(unit, host, use_pooled)?; + let (mut stream, is_recycled) = connect_socket(unit, socket_host, use_pooled)?; if is_recycled { debug!("sending request (reused connection) {} {}", method, url);