Replace getaddrinfo resolver with trust-dns-resolver
This commit is contained in:
		| @@ -27,7 +27,10 @@ serde = "1.0" | ||||
| serde_json = "1.0" | ||||
| serde_urlencoded = "0.5" | ||||
| tokio = "0.1.7" | ||||
| tokio-executor = "0.1.4" # a minimum version so trust-dns-resolver compiles | ||||
| tokio-io = "0.1" | ||||
| tokio-timer = "0.2.6" # a minimum version so trust-dns-resolver compiles | ||||
| trust-dns-resolver = "0.10" | ||||
| url = "1.2" | ||||
| uuid = { version = "0.7", features = ["v4"] } | ||||
| hyper-rustls = { version = "0.15", optional = true } | ||||
|   | ||||
| @@ -60,7 +60,6 @@ struct Config { | ||||
|     identity: Option<Identity>, | ||||
|     #[cfg(feature = "tls")] | ||||
|     tls: TLSBackend, | ||||
|     dns_threads: usize, | ||||
| } | ||||
|  | ||||
| impl ClientBuilder { | ||||
| @@ -88,7 +87,6 @@ impl ClientBuilder { | ||||
|                 identity: None, | ||||
|                 #[cfg(feature = "tls")] | ||||
|                 tls: TLSBackend::default(), | ||||
|                 dns_threads: 4, | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
| @@ -131,7 +129,7 @@ impl ClientBuilder { | ||||
|                         tls.identity(id); | ||||
|                     } | ||||
|  | ||||
|                     Connector::new_default_tls(config.dns_threads, tls, proxies.clone())? | ||||
|                     Connector::new_default_tls(tls, proxies.clone())? | ||||
|                 }, | ||||
|                 #[cfg(feature = "rustls-tls")] | ||||
|                 TLSBackend::Rustls => { | ||||
| @@ -188,12 +186,12 @@ impl ClientBuilder { | ||||
|                         tls.set_single_client_cert(certs, key); | ||||
|                     } | ||||
|  | ||||
|                     Connector::new_rustls_tls(config.dns_threads, tls, proxies.clone())? | ||||
|                     Connector::new_rustls_tls(tls, proxies.clone())? | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             #[cfg(not(feature = "tls"))] | ||||
|             Connector::new(config.dns_threads, proxies.clone()) | ||||
|             Connector::new(proxies.clone()) | ||||
|         }; | ||||
|  | ||||
|         let hyper_client = ::hyper::Client::builder() | ||||
| @@ -327,9 +325,9 @@ impl ClientBuilder { | ||||
|         self | ||||
|     } | ||||
|  | ||||
|     /// Set number of DNS threads. | ||||
|     pub fn dns_threads(mut self, threads: usize) -> ClientBuilder { | ||||
|         self.config.dns_threads = threads; | ||||
|     #[doc(hidden)] | ||||
|     #[deprecated(note = "DNS no longer uses blocking threads")] | ||||
|     pub fn dns_threads(self, _threads: usize) -> ClientBuilder { | ||||
|         self | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -281,13 +281,6 @@ impl ClientBuilder { | ||||
|         self | ||||
|     } | ||||
|  | ||||
|     /// Set the number of threads to use for DNS | ||||
|     /// | ||||
|     /// Default is 4 | ||||
|     pub fn dns_threads(self, threads: usize) -> ClientBuilder { | ||||
|         self.with_inner(|inner| inner.dns_threads(threads)) | ||||
|     } | ||||
|  | ||||
|     fn with_inner<F>(mut self, func: F) -> ClientBuilder | ||||
|     where | ||||
|         F: FnOnce(async_impl::ClientBuilder) -> async_impl::ClientBuilder, | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| use futures::Future; | ||||
| use http::uri::Scheme; | ||||
| use hyper::client::{HttpConnector}; | ||||
| use hyper::client::connect::{Connect, Connected, Destination}; | ||||
| use tokio_io::{AsyncRead, AsyncWrite}; | ||||
|  | ||||
| @@ -14,8 +13,11 @@ use bytes::BufMut; | ||||
| use std::io; | ||||
| use std::sync::Arc; | ||||
|  | ||||
| use dns::TrustDnsResolver; | ||||
| use Proxy; | ||||
|  | ||||
| type HttpConnector = ::hyper::client::HttpConnector<TrustDnsResolver>; | ||||
|  | ||||
|  | ||||
| pub(crate) struct Connector { | ||||
|     proxies: Arc<Vec<Proxy>>, | ||||
| @@ -33,8 +35,8 @@ enum Inner { | ||||
|  | ||||
| impl Connector { | ||||
|     #[cfg(not(feature = "tls"))] | ||||
|     pub(crate) fn new(threads: usize, proxies: Arc<Vec<Proxy>>) -> Connector { | ||||
|         let http = HttpConnector::new(threads); | ||||
|     pub(crate) fn new(proxies: Arc<Vec<Proxy>>) -> Connector { | ||||
|         let http = http_connector(); | ||||
|         Connector { | ||||
|             proxies, | ||||
|             inner: Inner::Http(http) | ||||
| @@ -42,10 +44,10 @@ impl Connector { | ||||
|     } | ||||
|  | ||||
|     #[cfg(feature = "default-tls")] | ||||
|     pub(crate) fn new_default_tls(threads: usize, tls: TlsConnectorBuilder, proxies: Arc<Vec<Proxy>>) -> ::Result<Connector> { | ||||
|     pub(crate) fn new_default_tls(tls: TlsConnectorBuilder, proxies: Arc<Vec<Proxy>>) -> ::Result<Connector> { | ||||
|         let tls = try_!(tls.build()); | ||||
|  | ||||
|         let mut http = HttpConnector::new(threads); | ||||
|         let mut http = http_connector(); | ||||
|         http.enforce_http(false); | ||||
|         let http = ::hyper_tls::HttpsConnector::from((http, tls.clone())); | ||||
|  | ||||
| @@ -56,8 +58,8 @@ impl Connector { | ||||
|     } | ||||
|  | ||||
|     #[cfg(feature = "rustls-tls")] | ||||
|     pub(crate) fn new_rustls_tls(threads: usize, tls: rustls::ClientConfig, proxies: Arc<Vec<Proxy>>) -> ::Result<Connector> { | ||||
|         let mut http = HttpConnector::new(threads); | ||||
|     pub(crate) fn new_rustls_tls(tls: rustls::ClientConfig, proxies: Arc<Vec<Proxy>>) -> ::Result<Connector> { | ||||
|         let mut http = http_connector(); | ||||
|         http.enforce_http(false); | ||||
|         let http = ::hyper_rustls::HttpsConnector::from((http, tls.clone())); | ||||
|  | ||||
| @@ -68,6 +70,11 @@ impl Connector { | ||||
|     } | ||||
| } | ||||
|  | ||||
| fn http_connector() -> HttpConnector { | ||||
|     let http = HttpConnector::new_with_resolver(TrustDnsResolver::new()); | ||||
|     http | ||||
| } | ||||
|  | ||||
| impl Connect for Connector { | ||||
|     type Transport = Conn; | ||||
|     type Error = io::Error; | ||||
|   | ||||
							
								
								
									
										73
									
								
								src/dns.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								src/dns.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| use std::io; | ||||
| use std::sync::{Arc, Mutex}; | ||||
|  | ||||
| use futures::{future, Future}; | ||||
| use hyper::client::connect::dns as hyper_dns; | ||||
| use trust_dns_resolver::AsyncResolver; | ||||
|  | ||||
| // If instead the type were just `AsyncResolver`, it breaks the default recursion limit | ||||
| // for the compiler to determine if `reqwest::Client` is `Send`. This is because `AsyncResolver` | ||||
| // has **a lot** of internal generic types that pushes us over the limit. | ||||
| // | ||||
| // "Erasing" the internal resolver type saves us from this limit. | ||||
| type ErasedResolver = Box<Fn(hyper_dns::Name) -> ::trust_dns_resolver::BackgroundLookupIp + Send + Sync>; | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub(crate) struct TrustDnsResolver { | ||||
|     inner: Arc<Mutex<Option<ErasedResolver>>>, | ||||
| } | ||||
|  | ||||
| impl TrustDnsResolver { | ||||
|     pub(crate) fn new() -> Self { | ||||
|         TrustDnsResolver { | ||||
|             inner: Arc::new(Mutex::new(None)), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl hyper_dns::Resolve for TrustDnsResolver { | ||||
|     type Addrs = ::std::vec::IntoIter<::std::net::IpAddr>; | ||||
|     type Future = Box<Future<Item=Self::Addrs, Error=io::Error> + Send>; | ||||
|  | ||||
|     fn resolve(&self, name: hyper_dns::Name) -> Self::Future { | ||||
|         let inner = self.inner.clone(); | ||||
|         Box::new(future::lazy(move || { | ||||
|             let mut inner = inner.lock().expect("lock resolver"); | ||||
|             if inner.is_none() { | ||||
|                 // The `bg` (background) future needs to be spawned onto an executor, | ||||
|                 // but a `reqwest::Client` may be constructed before an executor is ready. | ||||
|                 // So, the `bg` future cannot be spawned *until* the executor starts to | ||||
|                 // `poll` this future. | ||||
|                 match AsyncResolver::from_system_conf() { | ||||
|                     Ok((resolver, bg)) => { | ||||
|                         ::tokio::spawn(bg); | ||||
|                         *inner = Some(Box::new(move |name| { | ||||
|                             resolver.lookup_ip(name.as_str()) | ||||
|                         })); | ||||
|                     }, | ||||
|                     Err(err) => { | ||||
|                         return future::Either::A( | ||||
|                             future::err(io::Error::new(io::ErrorKind::Other, err.to_string())) | ||||
|                         ); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             future::Either::B((inner | ||||
|                 .as_mut() | ||||
|                 .expect("resolver is set"))(name) | ||||
|                 //.lookup_ip(name.as_str()) | ||||
|                 .map(|lookup| { | ||||
|                     lookup | ||||
|                         .iter() | ||||
|                         .collect::<Vec<_>>() | ||||
|                         .into_iter() | ||||
|                 }) | ||||
|                 .map_err(|err| { | ||||
|                     io::Error::new(io::ErrorKind::Other, err.to_string()) | ||||
|                 })) | ||||
|         })) | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -163,6 +163,7 @@ extern crate serde_urlencoded; | ||||
| extern crate tokio; | ||||
| #[cfg_attr(feature = "default-tls", macro_use)] | ||||
| extern crate tokio_io; | ||||
| extern crate trust_dns_resolver; | ||||
| extern crate url; | ||||
| extern crate uuid; | ||||
|  | ||||
| @@ -203,6 +204,7 @@ mod connect; | ||||
| mod connect_async; | ||||
| mod body; | ||||
| mod client; | ||||
| mod dns; | ||||
| mod into_url; | ||||
| mod proxy; | ||||
| mod redirect; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user