From c4bf42002131309cd16f2d674fd99ef84a8078fc Mon Sep 17 00:00:00 2001 From: Yannick Heinrich Date: Fri, 5 Oct 2018 14:02:31 +0200 Subject: [PATCH] Integrate helper functions inside corresponding structs --- src/async_impl/body.rs | 82 +++++++++++++++++---------------- src/async_impl/client.rs | 10 ++-- src/async_impl/decoder.rs | 94 +++++++++++++++++++------------------- src/async_impl/response.rs | 9 ++-- src/body.rs | 4 +- src/connect.rs | 4 +- src/error.rs | 2 - src/proxy.rs | 6 +-- src/tls.rs | 16 ++++--- 9 files changed, 111 insertions(+), 116 deletions(-) diff --git a/src/async_impl/body.rs b/src/async_impl/body.rs index 482f503..0b5b48a 100644 --- a/src/async_impl/body.rs +++ b/src/async_impl/body.rs @@ -28,6 +28,36 @@ impl Body { Inner::Hyper(ref body) => body.content_length(), } } + + #[inline] + pub(crate) fn wrap(body: ::hyper::Body) -> Body { + Body { + inner: Inner::Hyper(body), + } + } + + #[inline] + pub(crate) fn empty() -> Body { + Body { + inner: Inner::Hyper(::hyper::Body::empty()), + } + } + + #[inline] + pub(crate) fn reusable(chunk: Bytes) -> Body { + Body { + inner: Inner::Reusable(chunk), + } + } + + #[inline] + pub(crate) fn into_hyper(self) -> (Option, ::hyper::Body) { + match self.inner { + Inner::Reusable(chunk) => (Some(chunk.clone()), chunk.into()), + Inner::Hyper(b) => (None, b), + } +} + } impl Stream for Body { @@ -48,28 +78,28 @@ impl Stream for Body { impl From for Body { #[inline] fn from(bytes: Bytes) -> Body { - reusable(bytes) + Body::reusable(bytes) } } impl From> for Body { #[inline] fn from(vec: Vec) -> Body { - reusable(vec.into()) + Body::reusable(vec.into()) } } impl From<&'static [u8]> for Body { #[inline] fn from(s: &'static [u8]) -> Body { - reusable(Bytes::from_static(s)) + Body::reusable(Bytes::from_static(s)) } } impl From for Body { #[inline] fn from(s: String) -> Body { - reusable(s.into()) + Body::reusable(s.into()) } } @@ -88,6 +118,14 @@ pub struct Chunk { inner: ::hyper::Chunk, } +impl Chunk { + #[inline] + pub(crate) fn from_chunk(chunk: Bytes) -> Chunk { + Chunk { + inner: ::hyper::Chunk::from(chunk) + } + } +} impl Buf for Chunk { fn bytes(&self) -> &[u8] { self.inner.bytes() @@ -145,39 +183,3 @@ impl fmt::Debug for Chunk { fmt::Debug::fmt(&self.inner, f) } } - -#[inline] -pub(crate) fn wrap(body: ::hyper::Body) -> Body { - Body { - inner: Inner::Hyper(body), - } -} - -#[inline] -pub(crate) fn empty() -> Body { - Body { - inner: Inner::Hyper(::hyper::Body::empty()), - } -} - -#[inline] -pub(crate) fn chunk(chunk: Bytes) -> Chunk { - Chunk { - inner: ::hyper::Chunk::from(chunk) - } -} - -#[inline] -pub(crate) fn reusable(chunk: Bytes) -> Body { - Body { - inner: Inner::Reusable(chunk), - } -} - -#[inline] -pub(crate) fn into_hyper(body: Body) -> (Option, ::hyper::Body) { - match body.inner { - Inner::Reusable(chunk) => (Some(chunk.clone()), chunk.into()), - Inner::Hyper(b) => (None, b), - } -} diff --git a/src/async_impl/client.rs b/src/async_impl/client.rs index 187d0d9..56ec98e 100644 --- a/src/async_impl/client.rs +++ b/src/async_impl/client.rs @@ -11,7 +11,6 @@ use mime::{self}; use native_tls::{TlsConnector, TlsConnectorBuilder}; -use super::body; use super::request::{Request, RequestBuilder}; use super::response::Response; use connect::Connector; @@ -111,15 +110,13 @@ impl ClientBuilder { /// This can be used to connect to a server that has a self-signed /// certificate for example. pub fn add_root_certificate(mut self, cert: Certificate) -> ClientBuilder { - let cert = ::tls::cert(cert); - self.config.tls.add_root_certificate(cert); + self.config.tls.add_root_certificate(cert.cert()); self } /// Sets the identity to be used for client certificate authentication. pub fn identity(mut self, identity: Identity) -> ClientBuilder { - let pkcs12 = ::tls::pkcs12(identity); - self.config.tls.identity(pkcs12); + self.config.tls.identity(identity.pkcs12()); self } @@ -345,7 +342,7 @@ impl Client { let (reusable, body) = match body { Some(body) => { - let (reusable, body) = body::into_hyper(body); + let (reusable, body) = body.into_hyper(); (Some(reusable), body) }, None => { @@ -578,4 +575,3 @@ fn make_referer(next: &Url, previous: &Url) -> Option { referer.set_fragment(None); referer.as_str().parse().ok() } - diff --git a/src/async_impl/decoder.rs b/src/async_impl/decoder.rs index 43d83fb..ce2f6fc 100644 --- a/src/async_impl/decoder.rs +++ b/src/async_impl/decoder.rs @@ -32,7 +32,7 @@ use futures::{Async, Future, Poll, Stream}; use hyper::{HeaderMap}; use hyper::header::{CONTENT_ENCODING, CONTENT_LENGTH, TRANSFER_ENCODING, HeaderValue}; -use super::{body, Body, Chunk}; +use super::{Body, Chunk}; use error; const INIT_BUFFER_SIZE: usize = 8192; @@ -79,7 +79,7 @@ impl Decoder { #[inline] pub fn empty() -> Decoder { Decoder { - inner: Inner::PlainText(body::empty()) + inner: Inner::PlainText(Body::empty()) } } @@ -103,6 +103,48 @@ impl Decoder { } } + /// Constructs a Decoder from a hyper request. + /// + /// A decoder is just a wrapper around the hyper request that knows + /// how to decode the content body of the request. + /// + /// Uses the correct variant by inspecting the Content-Encoding header. + pub(crate) fn detect(headers: &mut HeaderMap, body: Body, check_gzip: bool) -> Decoder { + if !check_gzip { + return Decoder::plain_text(body); + } + let content_encoding_gzip: bool; + let mut is_gzip = { + content_encoding_gzip = headers + .get_all(CONTENT_ENCODING) + .iter() + .fold(false, |acc, enc| acc || enc == HeaderValue::from_static("gzip")); + content_encoding_gzip || + headers + .get_all(TRANSFER_ENCODING) + .iter() + .fold(false, |acc, enc| acc || enc == HeaderValue::from_static("gzip")) + }; + if is_gzip { + if let Some(content_length) = headers.get(CONTENT_LENGTH) { + if content_length == "0" { + warn!("GZipped response with content-length of 0"); + is_gzip = false; + } + } + } + if content_encoding_gzip { + headers.remove(CONTENT_ENCODING); + headers.remove(CONTENT_LENGTH); + } + if is_gzip { + Decoder::gzip(body) + } else { + Decoder::plain_text(body) + } + } + + pub(crate) fn content_length(&self) -> Option { match self.inner { Inner::PlainText(ref body) => body.content_length(), @@ -145,12 +187,12 @@ impl Future for Pending { Err(e) => return Err(e) }; - let body = mem::replace(&mut self.body, ReadableChunks::new(body::empty())); + let body = mem::replace(&mut self.body, ReadableChunks::new(Body::empty())); // libflate does a read_exact([0; 2]), so its impossible to tell // if the stream was empty, or truly had an UnexpectedEof. // Therefore, we need to check for EOF first. match body_state { - StreamState::Eof => Ok(Async::Ready(Inner::PlainText(body::empty()))), + StreamState::Eof => Ok(Async::Ready(Inner::PlainText(Body::empty()))), StreamState::HasMore => Ok(Async::Ready(Inner::Gzip(Gzip::new(body)))) } } @@ -190,7 +232,7 @@ impl Stream for Gzip { }, Ok(read) => { unsafe { self.buf.advance_mut(read) }; - let chunk = body::chunk(self.buf.split_to(read).freeze()); + let chunk = Chunk::from_chunk(self.buf.split_to(read).freeze()); Ok(Async::Ready(Some(chunk))) }, @@ -386,45 +428,3 @@ impl ReadableChunks } } } - -/// Constructs a Decoder from a hyper request. -/// -/// A decoder is just a wrapper around the hyper request that knows -/// how to decode the content body of the request. -/// -/// Uses the correct variant by inspecting the Content-Encoding header. -pub(crate) fn detect(headers: &mut HeaderMap, body: Body, check_gzip: bool) -> Decoder { - if !check_gzip { - return Decoder::plain_text(body); - } - let content_encoding_gzip: bool; - let mut is_gzip = { - content_encoding_gzip = headers - .get_all(CONTENT_ENCODING) - .iter() - .fold(false, |acc, enc| acc || enc == HeaderValue::from_static("gzip")); - content_encoding_gzip || - headers - .get_all(TRANSFER_ENCODING) - .iter() - .fold(false, |acc, enc| acc || enc == HeaderValue::from_static("gzip")) - }; - if is_gzip { - if let Some(content_length) = headers.get(CONTENT_LENGTH) { - if content_length == "0" { - warn!("GZipped response with content-length of 0"); - is_gzip = false; - } - } - } - if content_encoding_gzip { - headers.remove(CONTENT_ENCODING); - headers.remove(CONTENT_LENGTH); - } - if is_gzip { - Decoder::gzip(body) - } else { - Decoder::plain_text(body) - } -} - diff --git a/src/async_impl/response.rs b/src/async_impl/response.rs index 45f3e4e..4485a27 100644 --- a/src/async_impl/response.rs +++ b/src/async_impl/response.rs @@ -10,7 +10,8 @@ use serde_json; use url::Url; use http; -use super::{decoder, body, Decoder}; +use super::Decoder; +use super::body::Body; /// A Response to a submitted `Request`. @@ -29,7 +30,7 @@ impl Response { let status = res.status(); let version = res.version(); let mut headers = mem::replace(res.headers_mut(), HeaderMap::new()); - let decoder = decoder::detect(&mut headers, body::wrap(res.into_body()), gzip); + let decoder = Decoder::detect(&mut headers, Body::wrap(res.into_body()), gzip); debug!("Response: '{}' for {}", status, url); Response { status, @@ -145,11 +146,11 @@ impl fmt::Debug for Response { } } -impl> From> for Response { +impl> From> for Response { fn from(r: http::Response) -> Response { let (mut parts, body) = r.into_parts(); let body = body.into(); - let body = decoder::detect(&mut parts.headers, body, false); + let body = Decoder::detect(&mut parts.headers, body, false); let url = parts.extensions .remove::() .unwrap_or_else(|| ResponseUrl(Url::parse("http://no.url.provided.local").unwrap())); diff --git a/src/body.rs b/src/body.rs index 516e642..5e847b9 100644 --- a/src/body.rs +++ b/src/body.rs @@ -101,11 +101,11 @@ impl Body { body: (read, len), tx: tx, }; - (Some(tx), async_impl::body::wrap(rx), len) + (Some(tx), async_impl::Body::wrap(rx), len) }, Kind::Bytes(chunk) => { let len = chunk.len() as u64; - (None, async_impl::body::reusable(chunk), Some(len)) + (None, async_impl::Body::reusable(chunk), Some(len)) } } } diff --git a/src/connect.rs b/src/connect.rs index de9f4b0..4474b36 100644 --- a/src/connect.rs +++ b/src/connect.rs @@ -11,7 +11,7 @@ use connect_async::{TlsConnectorExt, TlsStream}; use std::io::{self, Cursor, Read, Write}; use std::sync::Arc; -use {proxy, Proxy}; +use Proxy; pub(crate) struct Connector { https: HttpsConnector, @@ -40,7 +40,7 @@ impl Connect for Connector { fn connect(&self, dst: Destination) -> Self::Future { for prox in self.proxies.iter() { - if let Some(puri) = proxy::intercept(prox, &dst) { + if let Some(puri) = prox.intercept(&dst) { trace!("proxy({:?}) intercepts {:?}", puri, dst); let mut ndst = dst.clone(); let new_scheme = puri diff --git a/src/error.rs b/src/error.rs index 7b3d799..807c42f 100644 --- a/src/error.rs +++ b/src/error.rs @@ -280,8 +280,6 @@ impl StdError for Error { } } -// pub(crate) - #[derive(Debug)] pub(crate) enum Kind { Http(::http::Error), diff --git a/src/proxy.rs b/src/proxy.rs index 37c722c..3d62722 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -128,7 +128,7 @@ impl Proxy { } } - fn intercept(&self, uri: &D) -> Option<::hyper::Uri> { + pub(crate) fn intercept(&self, uri: &D) -> Option<::hyper::Uri> { match self.intercept { Intercept::All(ref u) => Some(u.clone()), Intercept::Http(ref u) => { @@ -203,10 +203,6 @@ impl Dst for Destination { } } -pub(crate) fn intercept(proxy: &Proxy, uri: &Destination) -> Option<::http::Uri> { - proxy.intercept(uri) -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/tls.rs b/src/tls.rs index 8a631bb..37fe69c 100644 --- a/src/tls.rs +++ b/src/tls.rs @@ -55,6 +55,11 @@ impl Certificate { let inner = try_!(native_tls::Certificate::from_pem(der)); Ok(Certificate(inner)) } + + pub(crate) fn cert(self) -> native_tls::Certificate { + self.0 + } + } impl fmt::Debug for Certificate { @@ -104,6 +109,10 @@ impl Identity { let inner = try_!(native_tls::Identity::from_pkcs12(der, password)); Ok(Identity(inner)) } + + pub(crate) fn pkcs12(self) -> native_tls::Identity { + self.0 + } } impl fmt::Debug for Identity { @@ -113,10 +122,3 @@ impl fmt::Debug for Identity { } } -pub(crate) fn cert(cert: Certificate) -> native_tls::Certificate { - cert.0 -} - -pub(crate) fn pkcs12(identity: Identity) -> native_tls::Identity { - identity.0 -}