Merge pull request #152 from seanmonstar/proxy

add a `Proxy` type
This commit is contained in:
Sean McArthur
2017-06-22 11:40:56 -07:00
committed by GitHub
8 changed files with 481 additions and 16 deletions

View File

@@ -14,8 +14,10 @@ use tokio_core::reactor::Handle;
use super::body;
use super::request::{self, Request, RequestBuilder};
use super::response::{self, Response};
use connect::Connector;
use into_url::to_uri;
use redirect::{self, RedirectPolicy, check_redirect, remove_sensitive_headers};
use {Certificate, IntoUrl, Method, StatusCode, Url};
use {Certificate, IntoUrl, Method, proxy, Proxy, StatusCode, Url};
static DEFAULT_USER_AGENT: &'static str =
concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"));
@@ -79,6 +81,7 @@ pub struct ClientBuilder {
struct Config {
gzip: bool,
hostname_verification: bool,
proxies: Vec<Proxy>,
redirect_policy: RedirectPolicy,
referer: bool,
timeout: Option<Duration>,
@@ -97,6 +100,7 @@ impl ClientBuilder {
config: Some(Config {
gzip: true,
hostname_verification: true,
proxies: Vec::new(),
redirect_policy: RedirectPolicy::default(),
referer: true,
timeout: None,
@@ -127,7 +131,9 @@ impl ClientBuilder {
}
*/
let hyper_client = create_hyper_client(tls, handle);
let proxies = Arc::new(config.proxies);
let hyper_client = create_hyper_client(tls, proxies.clone(), handle);
//let mut hyper_client = create_hyper_client(tls_client);
//hyper_client.set_read_timeout(config.timeout);
@@ -137,6 +143,7 @@ impl ClientBuilder {
inner: Arc::new(ClientRef {
gzip: config.gzip,
hyper: hyper_client,
proxies: proxies,
redirect_policy: config.redirect_policy,
referer: config.referer,
}),
@@ -187,6 +194,13 @@ impl ClientBuilder {
self
}
/// Add a `Proxy` to the list of proxies the `Client` will use.
#[inline]
pub fn proxy(&mut self, proxy: Proxy) -> &mut ClientBuilder {
self.config_mut().proxies.push(proxy);
self
}
/// Set a `RedirectPolicy` for this client.
///
/// Default will follow redirects up to a maximum of 10.
@@ -226,14 +240,11 @@ impl ClientBuilder {
}
}
type HyperClient = ::hyper::Client<::hyper_tls::HttpsConnector<::hyper::client::HttpConnector>>;
type HyperClient = ::hyper::Client<Connector>;
fn create_hyper_client(tls: TlsConnector, handle: &Handle) -> HyperClient {
let mut http = ::hyper::client::HttpConnector::new(4, handle);
http.enforce_http(false);
let https = ::hyper_tls::HttpsConnector::from((http, tls));
fn create_hyper_client(tls: TlsConnector, proxies: Arc<Vec<Proxy>>, handle: &Handle) -> HyperClient {
::hyper::Client::configure()
.connector(https)
.connector(Connector::new(tls, proxies, handle))
.build(handle)
}
@@ -363,7 +374,8 @@ impl Client {
headers.set(AcceptEncoding(vec![qitem(Encoding::Gzip)]));
}
let mut req = ::hyper::Request::new(method.clone(), url_to_uri(&url));
let uri = to_uri(&url);
let mut req = ::hyper::Request::new(method.clone(), uri.clone());
*req.headers_mut() = headers.clone();
let body = body.and_then(|body| {
let (resuable, body) = body::into_hyper(body);
@@ -371,6 +383,10 @@ impl Client {
resuable
});
if proxy::is_proxied(&self.inner.proxies, &uri) {
req.set_proxy(true);
}
let in_flight = self.inner.hyper.request(req);
Pending {
@@ -408,6 +424,7 @@ impl fmt::Debug for ClientBuilder {
struct ClientRef {
gzip: bool,
hyper: HyperClient,
proxies: Arc<Vec<Proxy>>,
redirect_policy: RedirectPolicy,
referer: bool,
}
@@ -473,14 +490,18 @@ impl Future for Pending {
remove_sensitive_headers(&mut self.headers, &self.url, &self.urls);
debug!("redirecting to {:?} '{}'", self.method, self.url);
let uri = to_uri(&self.url);
let mut req = ::hyper::Request::new(
self.method.clone(),
url_to_uri(&self.url)
uri.clone()
);
*req.headers_mut() = self.headers.clone();
if let Some(ref body) = self.body {
req.set_body(body.clone());
}
if proxy::is_proxied(&self.client.proxies, &uri) {
req.set_proxy(true);
}
self.in_flight = self.client.hyper.request(req);
continue;
},
@@ -525,10 +546,6 @@ fn make_referer(next: &Url, previous: &Url) -> Option<Referer> {
Some(Referer::new(referer.into_string()))
}
fn url_to_uri(url: &Url) -> ::hyper::Uri {
url.as_str().parse().expect("a parsed Url should always be a valid Uri")
}
// pub(crate)
pub fn take_builder(builder: &mut ClientBuilder) -> ClientBuilder {