Integrate helper functions inside corresponding structs
This commit is contained in:
committed by
Sean McArthur
parent
647f59756e
commit
c4bf420021
@@ -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<Bytes>, ::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<Bytes> for Body {
|
||||
#[inline]
|
||||
fn from(bytes: Bytes) -> Body {
|
||||
reusable(bytes)
|
||||
Body::reusable(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<u8>> for Body {
|
||||
#[inline]
|
||||
fn from(vec: Vec<u8>) -> 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<String> 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<Bytes>, ::hyper::Body) {
|
||||
match body.inner {
|
||||
Inner::Reusable(chunk) => (Some(chunk.clone()), chunk.into()),
|
||||
Inner::Hyper(b) => (None, b),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<HeaderValue> {
|
||||
referer.set_fragment(None);
|
||||
referer.as_str().parse().ok()
|
||||
}
|
||||
|
||||
|
||||
@@ -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<u64> {
|
||||
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<S> ReadableChunks<S>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<T: Into<body::Body>> From<http::Response<T>> for Response {
|
||||
impl<T: Into<Body>> From<http::Response<T>> for Response {
|
||||
fn from(r: http::Response<T>) -> 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::<ResponseUrl>()
|
||||
.unwrap_or_else(|| ResponseUrl(Url::parse("http://no.url.provided.local").unwrap()));
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<HttpConnector>,
|
||||
@@ -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
|
||||
|
||||
@@ -280,8 +280,6 @@ impl StdError for Error {
|
||||
}
|
||||
}
|
||||
|
||||
// pub(crate)
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum Kind {
|
||||
Http(::http::Error),
|
||||
|
||||
@@ -128,7 +128,7 @@ impl Proxy {
|
||||
}
|
||||
}
|
||||
|
||||
fn intercept<D: Dst>(&self, uri: &D) -> Option<::hyper::Uri> {
|
||||
pub(crate) fn intercept<D: Dst>(&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::*;
|
||||
|
||||
16
src/tls.rs
16
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user