1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-12-02 19:12:24 +01:00

use flate2 released crate

This commit is contained in:
Nikolay Kim 2018-01-12 12:31:33 -08:00
parent 8a96e8fdd0
commit c470e7a02b
4 changed files with 93 additions and 29 deletions

View File

@ -69,7 +69,7 @@ script:
# Upload docs # Upload docs
after_success: after_success:
- | - |
if [[ "$TRAVIS_OS_NAME" == "linux" && "$TRAVIS_PULL_REQUEST" = "false" && "$TRAVIS_BRANCH" == "master" && "$TRAVIS_RUST_VERSION" == "nightly-2018-01-03" ]]; then if [[ "$TRAVIS_OS_NAME" == "linux" && "$TRAVIS_PULL_REQUEST" = "false" && "$TRAVIS_BRANCH" == "master" && "$TRAVIS_RUST_VERSION" == "1.20.0" ]]; then
cargo doc --features alpn --no-deps && cargo doc --features alpn --no-deps &&
echo "<meta http-equiv=refresh content=0;url=os_balloon/index.html>" > target/doc/index.html && echo "<meta http-equiv=refresh content=0;url=os_balloon/index.html>" > target/doc/index.html &&
cargo install mdbook && cargo install mdbook &&

View File

@ -1,7 +1,7 @@
# Changes # Changes
## 0.3.0 (2017-xx-xx) ## 0.3.0 (2018-01-12)
* HTTP/2 Support * HTTP/2 Support

View File

@ -36,10 +36,11 @@ alpn = ["openssl", "openssl/v102", "openssl/v110", "tokio-openssl"]
log = "0.4" log = "0.4"
failure = "0.1" failure = "0.1"
failure_derive = "0.1" failure_derive = "0.1"
time = "0.1" h2 = "0.1"
http = "^0.1.2" http = "^0.1.2"
httparse = "1.2" httparse = "1.2"
http-range = "0.1" http-range = "0.1"
time = "0.1"
mime = "0.3" mime = "0.3"
mime_guess = "1.8" mime_guess = "1.8"
regex = "0.2" regex = "0.2"
@ -54,8 +55,7 @@ smallvec = "0.6"
bitflags = "1.0" bitflags = "1.0"
num_cpus = "1.0" num_cpus = "1.0"
#flate2 = "1.0" flate2 = "1.0"
flate2 = { git="https://github.com/fafhrd91/flate2-rs.git" }
# temp solution # temp solution
# cookie = { version="0.10", features=["percent-encode", "secure"] } # cookie = { version="0.10", features=["percent-encode", "secure"] }
@ -69,8 +69,6 @@ futures = "0.1"
tokio-io = "0.1" tokio-io = "0.1"
tokio-core = "0.1" tokio-core = "0.1"
h2 = { git = 'https://github.com/carllerche/h2' }
# native-tls # native-tls
native-tls = { version="0.1", optional = true } native-tls = { version="0.1", optional = true }
tokio-tls = { version="0.1", optional = true } tokio-tls = { version="0.1", optional = true }

View File

@ -1,5 +1,5 @@
use std::{io, cmp, mem}; use std::{io, cmp, mem};
use std::io::Write; use std::io::{Read, Write};
use std::fmt::Write as FmtWrite; use std::fmt::Write as FmtWrite;
use std::str::FromStr; use std::str::FromStr;
@ -8,7 +8,8 @@ use http::header::{HeaderMap, HeaderValue,
ACCEPT_ENCODING, CONNECTION, ACCEPT_ENCODING, CONNECTION,
CONTENT_ENCODING, CONTENT_LENGTH, TRANSFER_ENCODING}; CONTENT_ENCODING, CONTENT_LENGTH, TRANSFER_ENCODING};
use flate2::Compression; use flate2::Compression;
use flate2::write::{GzDecoder, GzEncoder, DeflateDecoder, DeflateEncoder}; use flate2::read::GzDecoder;
use flate2::write::{GzEncoder, DeflateDecoder, DeflateEncoder};
use brotli2::write::{BrotliDecoder, BrotliEncoder}; use brotli2::write::{BrotliDecoder, BrotliEncoder};
use bytes::{Bytes, BytesMut, BufMut, Writer}; use bytes::{Bytes, BytesMut, BufMut, Writer};
@ -122,15 +123,50 @@ impl PayloadWriter for PayloadType {
enum Decoder { enum Decoder {
Deflate(Box<DeflateDecoder<Writer<BytesMut>>>), Deflate(Box<DeflateDecoder<Writer<BytesMut>>>),
Gzip(Box<GzDecoder<Writer<BytesMut>>>), Gzip(Option<Box<GzDecoder<Wrapper>>>),
Br(Box<BrotliDecoder<Writer<BytesMut>>>), Br(Box<BrotliDecoder<Writer<BytesMut>>>),
Identity, Identity,
} }
// should go after write::GzDecoder get implemented
#[derive(Debug)]
struct Wrapper {
buf: BytesMut,
eof: bool,
}
impl io::Read for Wrapper {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let len = cmp::min(buf.len(), self.buf.len());
buf[..len].copy_from_slice(&self.buf[..len]);
self.buf.split_to(len);
if len == 0 {
if self.eof {
Ok(0)
} else {
Err(io::Error::new(io::ErrorKind::WouldBlock, ""))
}
} else {
Ok(len)
}
}
}
impl io::Write for Wrapper {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.buf.extend_from_slice(buf);
Ok(buf.len())
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
/// Payload wrapper with content decompression support /// Payload wrapper with content decompression support
pub(crate) struct EncodedPayload { pub(crate) struct EncodedPayload {
inner: PayloadSender, inner: PayloadSender,
decoder: Decoder, decoder: Decoder,
dst: BytesMut,
error: bool, error: bool,
} }
@ -141,11 +177,10 @@ impl EncodedPayload {
Box::new(BrotliDecoder::new(BytesMut::with_capacity(8192).writer()))), Box::new(BrotliDecoder::new(BytesMut::with_capacity(8192).writer()))),
ContentEncoding::Deflate => Decoder::Deflate( ContentEncoding::Deflate => Decoder::Deflate(
Box::new(DeflateDecoder::new(BytesMut::with_capacity(8192).writer()))), Box::new(DeflateDecoder::new(BytesMut::with_capacity(8192).writer()))),
ContentEncoding::Gzip => Decoder::Gzip( ContentEncoding::Gzip => Decoder::Gzip(None),
Box::new(GzDecoder::new(BytesMut::with_capacity(8192).writer()))),
_ => Decoder::Identity, _ => Decoder::Identity,
}; };
EncodedPayload{ inner: inner, decoder: dec, error: false } EncodedPayload{ inner: inner, decoder: dec, error: false, dst: BytesMut::new() }
} }
} }
@ -174,16 +209,28 @@ impl PayloadWriter for EncodedPayload {
} }
}, },
Decoder::Gzip(ref mut decoder) => { Decoder::Gzip(ref mut decoder) => {
match decoder.try_finish() { if let Some(ref mut decoder) = *decoder {
Ok(_) => { decoder.as_mut().get_mut().eof = true;
let b = decoder.get_mut().get_mut().take().freeze();
if !b.is_empty() { loop {
self.inner.feed_data(b); self.dst.reserve(8192);
} match decoder.read(unsafe{self.dst.bytes_mut()}) {
Ok(n) => {
if n == 0 {
self.inner.feed_eof(); self.inner.feed_eof();
return return
}, } else {
Err(err) => Some(err), unsafe{self.dst.set_len(n)};
self.inner.feed_data(self.dst.split_to(n).freeze());
}
}
Err(err) => {
break Some(err);
}
}
}
} else {
return
} }
}, },
Decoder::Deflate(ref mut decoder) => { Decoder::Deflate(ref mut decoder) => {
@ -231,14 +278,33 @@ impl PayloadWriter for EncodedPayload {
} }
Decoder::Gzip(ref mut decoder) => { Decoder::Gzip(ref mut decoder) => {
if decoder.write(&data).is_ok() && decoder.flush().is_ok() { if decoder.is_none() {
let b = decoder.get_mut().get_mut().take().freeze(); *decoder = Some(
if !b.is_empty() { Box::new(GzDecoder::new(
self.inner.feed_data(b); Wrapper{buf: BytesMut::from(data), eof: false})));
} else {
let _ = decoder.as_mut().unwrap().write(&data);
} }
loop {
self.dst.reserve(8192);
match decoder.as_mut().as_mut().unwrap().read(unsafe{self.dst.bytes_mut()}) {
Ok(n) => {
if n == 0 {
return
} else {
unsafe{self.dst.set_len(n)};
self.inner.feed_data(self.dst.split_to(n).freeze());
}
}
Err(e) => {
if e.kind() == io::ErrorKind::WouldBlock {
return return
} }
trace!("Error decoding gzip encoding"); break
}
}
}
} }
Decoder::Deflate(ref mut decoder) => { Decoder::Deflate(ref mut decoder) => {