From 3554b0ad2663083bf54913739866819c52dc3336 Mon Sep 17 00:00:00 2001 From: quininer Date: Wed, 20 Mar 2019 04:21:43 +0800 Subject: [PATCH] replace libflate with flate2 (#476) --- Cargo.toml | 3 +- src/async_impl/decoder.rs | 110 +++++--------------------------------- src/lib.rs | 2 +- 3 files changed, 17 insertions(+), 98 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 144d005..f6d219e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ http = "0.1.15" hyper = "0.12.22" hyper-old-types = { version = "0.11", optional = true, features = ["compat"] } hyper-tls = { version = "0.3", optional = true } -libflate = "0.1.18" +flate2 = { version = "^1.0.7", default-features = false, features = ["rust_backend"] } log = "0.4" mime = "0.3.7" mime_guess = "2.0.0-alpha.6" @@ -44,6 +44,7 @@ rustls = { version = "0.15", features = ["dangerous_configuration"], optional = env_logger = "0.6" serde_derive = "1.0" tokio-tcp = "0.1" +libflate = "0.1" [features] default = ["default-tls"] diff --git a/src/async_impl/decoder.rs b/src/async_impl/decoder.rs index 25f2f16..c909536 100644 --- a/src/async_impl/decoder.rs +++ b/src/async_impl/decoder.rs @@ -18,7 +18,6 @@ This module consists of a few main types: The following types directly support the gzip compression case: - `Pending` is a non-blocking constructor for a `Decoder` in case the body needs to be checked for EOF -- `Peeked` is a buffer that keeps a few bytes available so `libflate`s `read_exact` calls won't fail */ use std::fmt; @@ -27,7 +26,7 @@ use std::cmp; use std::io::{self, Read}; use bytes::{Buf, BufMut, BytesMut}; -use libflate::non_blocking::gzip; +use flate2::read::GzDecoder; use futures::{Async, Future, Poll, Stream}; use hyper::{HeaderMap}; use hyper::header::{CONTENT_ENCODING, CONTENT_LENGTH, TRANSFER_ENCODING}; @@ -38,7 +37,7 @@ use error; const INIT_BUFFER_SIZE: usize = 8192; /// A response decompressor over a non-blocking stream of chunks. -/// +/// /// The inner decoder may be constructed asynchronously. pub struct Decoder { inner: Inner @@ -58,10 +57,10 @@ struct Pending { body: ReadableChunks, } -/// A gzip decoder that reads from a `libflate::gzip::Decoder` into a `BytesMut` and emits the results +/// A gzip decoder that reads from a `flate2::read::GzDecoder` into a `BytesMut` and emits the results /// as a `Chunk`. struct Gzip { - inner: Box>>>, + inner: Box>>, buf: BytesMut, } @@ -74,7 +73,7 @@ impl fmt::Debug for Decoder { impl Decoder { /// An empty decoder. - /// + /// /// This decoder will produce a single 0 byte chunk. #[inline] pub fn empty() -> Decoder { @@ -84,7 +83,7 @@ impl Decoder { } /// A plain text decoder. - /// + /// /// This decoder will emit the underlying chunks as-is. #[inline] fn plain_text(body: Body) -> Decoder { @@ -94,7 +93,7 @@ impl Decoder { } /// A gzip decoder. - /// + /// /// This decoder will buffer and decompress chunks that are gzipped. #[inline] fn gzip(body: Body) -> Decoder { @@ -188,9 +187,6 @@ impl Future for Pending { }; 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::HasMore => Ok(Async::Ready(Inner::Gzip(Gzip::new(body)))) @@ -202,7 +198,7 @@ impl Gzip { fn new(stream: ReadableChunks) -> Self { Gzip { buf: BytesMut::with_capacity(INIT_BUFFER_SIZE), - inner: Box::new(gzip::Decoder::new(Peeked::new(stream))), + inner: Box::new(GzDecoder::new(stream)), } } } @@ -217,10 +213,10 @@ impl Stream for Gzip { } // The buffer contains uninitialised memory so getting a readable slice is unsafe. - // We trust the `libflate` writer not to read from the memory given. - // - // To be safe, this memory could be zeroed before passing to `libflate`. - // Otherwise we might need to deal with the case where `libflate` panics. + // We trust the `flate2` and `miniz` writer not to read from the memory given. + // + // To be safe, this memory could be zeroed before passing to `flate2`. + // Otherwise we might need to deal with the case where `flate2` panics. let read = { let mut buf = unsafe { self.buf.bytes_mut() }; self.inner.read(&mut buf) @@ -266,84 +262,6 @@ enum StreamState { Eof } -/// A buffering reader that ensures `Read`s return at least a few bytes. -struct Peeked { - state: PeekedState, - peeked_buf: [u8; 2], - pos: usize, - inner: R, -} - -enum PeekedState { - /// The internal buffer hasn't filled yet. - NotReady, - /// The internal buffer can be read. - Ready(usize) -} - -impl Peeked { - #[inline] - fn new(inner: R) -> Self { - Peeked { - state: PeekedState::NotReady, - peeked_buf: [0; 2], - inner: inner, - pos: 0, - } - } - - #[inline] - fn ready(&mut self) { - self.state = PeekedState::Ready(self.pos); - self.pos = 0; - } - - #[inline] - fn not_ready(&mut self) { - self.state = PeekedState::NotReady; - self.pos = 0; - } -} - -impl Read for Peeked { - #[inline] - fn read(&mut self, buf: &mut [u8]) -> io::Result { - loop { - match self.state { - PeekedState::Ready(peeked_buf_len) => { - let len = cmp::min(buf.len(), peeked_buf_len - self.pos); - let start = self.pos; - let end = self.pos + len; - - buf[..len].copy_from_slice(&self.peeked_buf[start..end]); - self.pos += len; - if self.pos == peeked_buf_len { - self.not_ready(); - } - - return Ok(len) - }, - PeekedState::NotReady => { - let read = self.inner.read(&mut self.peeked_buf[self.pos..]); - - match read { - Ok(0) => { - self.ready(); - }, - Ok(read) => { - self.pos += read; - if self.pos == self.peeked_buf.len() { - self.ready(); - } - }, - Err(e) => return Err(e) - } - } - }; - } - } -} - impl ReadableChunks { #[inline] pub(crate) fn new(stream: S) -> Self { @@ -402,11 +320,11 @@ where } } -impl ReadableChunks +impl ReadableChunks where S: Stream { /// Poll the readiness of the inner reader. - /// + /// /// This function will update the internal state and return a simplified /// version of the `ReadState`. fn poll_stream(&mut self) -> Poll { diff --git a/src/lib.rs b/src/lib.rs index ef8314c..b71329f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -184,7 +184,7 @@ pub extern crate hyper_old_types as hyper_011; extern crate hyper_tls; #[macro_use] extern crate log; -extern crate libflate; +extern crate flate2; extern crate mime; extern crate mime_guess; #[cfg(feature = "default-tls")]