change ClientBuilders to by-value builders
This commit is contained in:
@@ -37,8 +37,7 @@ pub struct Client {
|
|||||||
|
|
||||||
/// A `ClientBuilder` can be used to create a `Client` with custom configuration:
|
/// A `ClientBuilder` can be used to create a `Client` with custom configuration:
|
||||||
pub struct ClientBuilder {
|
pub struct ClientBuilder {
|
||||||
config: Option<Config>,
|
config: Config,
|
||||||
err: Option<::Error>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
@@ -62,7 +61,7 @@ impl ClientBuilder {
|
|||||||
headers.insert(ACCEPT, HeaderValue::from_str(mime::STAR_STAR.as_ref()).expect("unable to parse mime"));
|
headers.insert(ACCEPT, HeaderValue::from_str(mime::STAR_STAR.as_ref()).expect("unable to parse mime"));
|
||||||
|
|
||||||
ClientBuilder {
|
ClientBuilder {
|
||||||
config: Some(Config {
|
config: Config {
|
||||||
gzip: true,
|
gzip: true,
|
||||||
headers: headers,
|
headers: headers,
|
||||||
hostname_verification: true,
|
hostname_verification: true,
|
||||||
@@ -73,8 +72,7 @@ impl ClientBuilder {
|
|||||||
timeout: None,
|
timeout: None,
|
||||||
tls: TlsConnector::builder(),
|
tls: TlsConnector::builder(),
|
||||||
dns_threads: 4,
|
dns_threads: 4,
|
||||||
}),
|
},
|
||||||
err: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,18 +81,8 @@ impl ClientBuilder {
|
|||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// This method fails if native TLS backend cannot be initialized.
|
/// This method fails if native TLS backend cannot be initialized.
|
||||||
///
|
pub fn build(self) -> ::Result<Client> {
|
||||||
/// # Panics
|
let mut config = self.config;
|
||||||
///
|
|
||||||
/// This method consumes the internal state of the builder.
|
|
||||||
/// Trying to use this builder again after calling `build` will panic.
|
|
||||||
pub fn build(&mut self) -> ::Result<Client> {
|
|
||||||
if let Some(err) = self.err.take() {
|
|
||||||
return Err(err);
|
|
||||||
}
|
|
||||||
let mut config = self.config
|
|
||||||
.take()
|
|
||||||
.expect("ClientBuilder cannot be reused after building a Client");
|
|
||||||
|
|
||||||
config.tls.danger_accept_invalid_hostnames(!config.hostname_verification);
|
config.tls.danger_accept_invalid_hostnames(!config.hostname_verification);
|
||||||
config.tls.danger_accept_invalid_certs(!config.certs_verification);
|
config.tls.danger_accept_invalid_certs(!config.certs_verification);
|
||||||
@@ -123,20 +111,16 @@ impl ClientBuilder {
|
|||||||
///
|
///
|
||||||
/// This can be used to connect to a server that has a self-signed
|
/// This can be used to connect to a server that has a self-signed
|
||||||
/// certificate for example.
|
/// certificate for example.
|
||||||
pub fn add_root_certificate(&mut self, cert: Certificate) -> &mut ClientBuilder {
|
pub fn add_root_certificate(mut self, cert: Certificate) -> ClientBuilder {
|
||||||
if let Some(config) = config_mut(&mut self.config, &self.err) {
|
let cert = ::tls::cert(cert);
|
||||||
let cert = ::tls::cert(cert);
|
self.config.tls.add_root_certificate(cert);
|
||||||
config.tls.add_root_certificate(cert);
|
|
||||||
}
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the identity to be used for client certificate authentication.
|
/// Sets the identity to be used for client certificate authentication.
|
||||||
pub fn identity(&mut self, identity: Identity) -> &mut ClientBuilder {
|
pub fn identity(mut self, identity: Identity) -> ClientBuilder {
|
||||||
if let Some(config) = config_mut(&mut self.config, &self.err) {
|
let pkcs12 = ::tls::pkcs12(identity);
|
||||||
let pkcs12 = ::tls::pkcs12(identity);
|
self.config.tls.identity(pkcs12);
|
||||||
config.tls.identity(pkcs12);
|
|
||||||
}
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,10 +135,8 @@ impl ClientBuilder {
|
|||||||
/// site will be trusted for use from any other. This introduces a
|
/// site will be trusted for use from any other. This introduces a
|
||||||
/// significant vulnerability to man-in-the-middle attacks.
|
/// significant vulnerability to man-in-the-middle attacks.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn danger_accept_invalid_hostnames(&mut self, accept_invalid_hostname: bool) -> &mut ClientBuilder {
|
pub fn danger_accept_invalid_hostnames(mut self, accept_invalid_hostname: bool) -> ClientBuilder {
|
||||||
if let Some(config) = config_mut(&mut self.config, &self.err) {
|
self.config.hostname_verification = !accept_invalid_hostname;
|
||||||
config.hostname_verification = !accept_invalid_hostname;
|
|
||||||
}
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,21 +153,17 @@ impl ClientBuilder {
|
|||||||
/// introduces significant vulnerabilities, and should only be used
|
/// introduces significant vulnerabilities, and should only be used
|
||||||
/// as a last resort.
|
/// as a last resort.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn danger_accept_invalid_certs(&mut self, accept_invalid_certs: bool) -> &mut ClientBuilder {
|
pub fn danger_accept_invalid_certs(mut self, accept_invalid_certs: bool) -> ClientBuilder {
|
||||||
if let Some(config) = config_mut(&mut self.config, &self.err) {
|
self.config.certs_verification = !accept_invalid_certs;
|
||||||
config.certs_verification = !accept_invalid_certs;
|
|
||||||
}
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Sets the default headers for every request.
|
/// Sets the default headers for every request.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn default_headers(&mut self, headers: HeaderMap) -> &mut ClientBuilder {
|
pub fn default_headers(mut self, headers: HeaderMap) -> ClientBuilder {
|
||||||
if let Some(config) = config_mut(&mut self.config, &self.err) {
|
for (key, value) in headers.iter() {
|
||||||
for (key, value) in headers.iter() {
|
self.config.headers.insert(key, value.clone());
|
||||||
config.headers.insert(key, value.clone());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -194,19 +172,15 @@ impl ClientBuilder {
|
|||||||
///
|
///
|
||||||
/// Default is enabled.
|
/// Default is enabled.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn gzip(&mut self, enable: bool) -> &mut ClientBuilder {
|
pub fn gzip(mut self, enable: bool) -> ClientBuilder {
|
||||||
if let Some(config) = config_mut(&mut self.config, &self.err) {
|
self.config.gzip = enable;
|
||||||
config.gzip = enable;
|
|
||||||
}
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a `Proxy` to the list of proxies the `Client` will use.
|
/// Add a `Proxy` to the list of proxies the `Client` will use.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn proxy(&mut self, proxy: Proxy) -> &mut ClientBuilder {
|
pub fn proxy(mut self, proxy: Proxy) -> ClientBuilder {
|
||||||
if let Some(config) = config_mut(&mut self.config, &self.err) {
|
self.config.proxies.push(proxy);
|
||||||
config.proxies.push(proxy);
|
|
||||||
}
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,10 +188,8 @@ impl ClientBuilder {
|
|||||||
///
|
///
|
||||||
/// Default will follow redirects up to a maximum of 10.
|
/// Default will follow redirects up to a maximum of 10.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn redirect(&mut self, policy: RedirectPolicy) -> &mut ClientBuilder {
|
pub fn redirect(mut self, policy: RedirectPolicy) -> ClientBuilder {
|
||||||
if let Some(config) = config_mut(&mut self.config, &self.err) {
|
self.config.redirect_policy = policy;
|
||||||
config.redirect_policy = policy;
|
|
||||||
}
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,40 +197,26 @@ impl ClientBuilder {
|
|||||||
///
|
///
|
||||||
/// Default is `true`.
|
/// Default is `true`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn referer(&mut self, enable: bool) -> &mut ClientBuilder {
|
pub fn referer(mut self, enable: bool) -> ClientBuilder {
|
||||||
if let Some(config) = config_mut(&mut self.config, &self.err) {
|
self.config.referer = enable;
|
||||||
config.referer = enable;
|
|
||||||
}
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a timeout for both the read and write operations of a client.
|
/// Set a timeout for both the read and write operations of a client.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn timeout(&mut self, timeout: Duration) -> &mut ClientBuilder {
|
pub fn timeout(mut self, timeout: Duration) -> ClientBuilder {
|
||||||
if let Some(config) = config_mut(&mut self.config, &self.err) {
|
self.config.timeout = Some(timeout);
|
||||||
config.timeout = Some(timeout);
|
|
||||||
}
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set number of DNS threads.
|
/// Set number of DNS threads.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn dns_threads(&mut self, threads: usize) -> &mut ClientBuilder {
|
pub fn dns_threads(mut self, threads: usize) -> ClientBuilder {
|
||||||
if let Some(config) = config_mut(&mut self.config, &self.err) {
|
self.config.dns_threads = threads;
|
||||||
config.dns_threads = threads;
|
|
||||||
}
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn config_mut<'a>(config: &'a mut Option<Config>, err: &Option<::Error>) -> Option<&'a mut Config> {
|
|
||||||
if err.is_some() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
config.as_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type HyperClient = ::hyper::Client<Connector>;
|
type HyperClient = ::hyper::Client<Connector>;
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
@@ -608,11 +566,6 @@ fn make_referer(next: &Url, previous: &Url) -> Option<HeaderValue> {
|
|||||||
|
|
||||||
// pub(crate)
|
// pub(crate)
|
||||||
|
|
||||||
pub fn take_builder(builder: &mut ClientBuilder) -> ClientBuilder {
|
|
||||||
use std::mem;
|
|
||||||
mem::replace(builder, ClientBuilder { config: None, err: None })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pending_err(err: ::Error) -> Pending {
|
pub fn pending_err(err: ::Error) -> Pending {
|
||||||
Pending {
|
Pending {
|
||||||
inner: PendingInner::Error(Some(err)),
|
inner: PendingInner::Error(Some(err)),
|
||||||
|
|||||||
@@ -70,12 +70,7 @@ impl ClientBuilder {
|
|||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// This method fails if native TLS backend cannot be initialized.
|
/// This method fails if native TLS backend cannot be initialized.
|
||||||
///
|
pub fn build(self) -> ::Result<Client> {
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// This method consumes the internal state of the builder.
|
|
||||||
/// Trying to use this builder again after calling `build` will panic.
|
|
||||||
pub fn build(&mut self) -> ::Result<Client> {
|
|
||||||
ClientHandle::new(self).map(|handle| Client {
|
ClientHandle::new(self).map(|handle| Client {
|
||||||
inner: handle,
|
inner: handle,
|
||||||
})
|
})
|
||||||
@@ -110,9 +105,8 @@ impl ClientBuilder {
|
|||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// This method fails if adding root certificate was unsuccessful.
|
/// This method fails if adding root certificate was unsuccessful.
|
||||||
pub fn add_root_certificate(&mut self, cert: Certificate) -> &mut ClientBuilder {
|
pub fn add_root_certificate(self, cert: Certificate) -> ClientBuilder {
|
||||||
self.inner.add_root_certificate(cert);
|
self.with_inner(move |inner| inner.add_root_certificate(cert))
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the identity to be used for client certificate authentication.
|
/// Sets the identity to be used for client certificate authentication.
|
||||||
@@ -138,9 +132,8 @@ impl ClientBuilder {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn identity(&mut self, identity: Identity) -> &mut ClientBuilder {
|
pub fn identity(self, identity: Identity) -> ClientBuilder {
|
||||||
self.inner.identity(identity);
|
self.with_inner(move |inner| inner.identity(identity))
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -155,9 +148,8 @@ impl ClientBuilder {
|
|||||||
/// site will be trusted for use from any other. This introduces a
|
/// site will be trusted for use from any other. This introduces a
|
||||||
/// significant vulnerability to man-in-the-middle attacks.
|
/// significant vulnerability to man-in-the-middle attacks.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn danger_accept_invalid_hostnames(&mut self, accept_invalid_hostname: bool) -> &mut ClientBuilder {
|
pub fn danger_accept_invalid_hostnames(self, accept_invalid_hostname: bool) -> ClientBuilder {
|
||||||
self.inner.danger_accept_invalid_hostnames(accept_invalid_hostname);
|
self.with_inner(|inner| inner.danger_accept_invalid_hostnames(accept_invalid_hostname))
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -173,9 +165,8 @@ impl ClientBuilder {
|
|||||||
/// introduces significant vulnerabilities, and should only be used
|
/// introduces significant vulnerabilities, and should only be used
|
||||||
/// as a last resort.
|
/// as a last resort.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn danger_accept_invalid_certs(&mut self, accept_invalid_certs: bool) -> &mut ClientBuilder {
|
pub fn danger_accept_invalid_certs(self, accept_invalid_certs: bool) -> ClientBuilder {
|
||||||
self.inner.danger_accept_invalid_certs(accept_invalid_certs);
|
self.with_inner(|inner| inner.danger_accept_invalid_certs(accept_invalid_certs))
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the default headers for every request.
|
/// Sets the default headers for every request.
|
||||||
@@ -217,43 +208,38 @@ impl ClientBuilder {
|
|||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn default_headers(&mut self, headers: header::HeaderMap) -> &mut ClientBuilder {
|
pub fn default_headers(self, headers: header::HeaderMap) -> ClientBuilder {
|
||||||
self.inner.default_headers(headers);
|
self.with_inner(move |inner| inner.default_headers(headers))
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enable auto gzip decompression by checking the ContentEncoding response header.
|
/// Enable auto gzip decompression by checking the ContentEncoding response header.
|
||||||
///
|
///
|
||||||
/// Default is enabled.
|
/// Default is enabled.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn gzip(&mut self, enable: bool) -> &mut ClientBuilder {
|
pub fn gzip(self, enable: bool) -> ClientBuilder {
|
||||||
self.inner.gzip(enable);
|
self.with_inner(|inner| inner.gzip(enable))
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a `Proxy` to the list of proxies the `Client` will use.
|
/// Add a `Proxy` to the list of proxies the `Client` will use.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn proxy(&mut self, proxy: Proxy) -> &mut ClientBuilder {
|
pub fn proxy(self, proxy: Proxy) -> ClientBuilder {
|
||||||
self.inner.proxy(proxy);
|
self.with_inner(move |inner| inner.proxy(proxy))
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a `RedirectPolicy` for this client.
|
/// Set a `RedirectPolicy` for this client.
|
||||||
///
|
///
|
||||||
/// Default will follow redirects up to a maximum of 10.
|
/// Default will follow redirects up to a maximum of 10.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn redirect(&mut self, policy: RedirectPolicy) -> &mut ClientBuilder {
|
pub fn redirect(self, policy: RedirectPolicy) -> ClientBuilder {
|
||||||
self.inner.redirect(policy);
|
self.with_inner(move |inner| inner.redirect(policy))
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enable or disable automatic setting of the `Referer` header.
|
/// Enable or disable automatic setting of the `Referer` header.
|
||||||
///
|
///
|
||||||
/// Default is `true`.
|
/// Default is `true`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn referer(&mut self, enable: bool) -> &mut ClientBuilder {
|
pub fn referer(self, enable: bool) -> ClientBuilder {
|
||||||
self.inner.referer(enable);
|
self.with_inner(|inner| inner.referer(enable))
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a timeout for connect, read and write operations of a `Client`.
|
/// Set a timeout for connect, read and write operations of a `Client`.
|
||||||
@@ -262,12 +248,20 @@ impl ClientBuilder {
|
|||||||
///
|
///
|
||||||
/// Pass `None` to disable timeout.
|
/// Pass `None` to disable timeout.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn timeout<T>(&mut self, timeout: T) -> &mut ClientBuilder
|
pub fn timeout<T>(mut self, timeout: T) -> ClientBuilder
|
||||||
where T: Into<Option<Duration>>,
|
where T: Into<Option<Duration>>,
|
||||||
{
|
{
|
||||||
self.timeout = Timeout(timeout.into());
|
self.timeout = Timeout(timeout.into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn with_inner<F>(mut self, func: F) -> ClientBuilder
|
||||||
|
where
|
||||||
|
F: FnOnce(async_impl::ClientBuilder) -> async_impl::ClientBuilder,
|
||||||
|
{
|
||||||
|
self.inner = func(self.inner);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -417,10 +411,9 @@ impl Drop for InnerClientHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ClientHandle {
|
impl ClientHandle {
|
||||||
fn new(builder: &mut ClientBuilder) -> ::Result<ClientHandle> {
|
fn new(builder: ClientBuilder) -> ::Result<ClientHandle> {
|
||||||
|
|
||||||
let timeout = builder.timeout;
|
let timeout = builder.timeout;
|
||||||
let mut builder = async_impl::client::take_builder(&mut builder.inner);
|
let builder = builder.inner;
|
||||||
let (tx, rx) = mpsc::unbounded();
|
let (tx, rx) = mpsc::unbounded();
|
||||||
let (spawn_tx, spawn_rx) = oneshot::channel::<::Result<()>>();
|
let (spawn_tx, spawn_rx) = oneshot::channel::<::Result<()>>();
|
||||||
let handle = try_!(thread::Builder::new().name("reqwest-internal-sync-runtime".into()).spawn(move || {
|
let handle = try_!(thread::Builder::new().name("reqwest-internal-sync-runtime".into()).spawn(move || {
|
||||||
|
|||||||
Reference in New Issue
Block a user