mirror of
https://github.com/actix/actix-web.git
synced 2024-12-23 08:36:34 +00:00
use flate2 released crate
This commit is contained in:
parent
8a96e8fdd0
commit
c470e7a02b
4 changed files with 93 additions and 29 deletions
|
@ -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 &&
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
|
|
||||||
## 0.3.0 (2017-xx-xx)
|
## 0.3.0 (2018-01-12)
|
||||||
|
|
||||||
* HTTP/2 Support
|
* HTTP/2 Support
|
||||||
|
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
|
@ -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();
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
unsafe{self.dst.set_len(n)};
|
||||||
|
self.inner.feed_data(self.dst.split_to(n).freeze());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
break Some(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.inner.feed_eof();
|
}
|
||||||
return
|
} else {
|
||||||
},
|
return
|
||||||
Err(err) => Some(err),
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
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 {
|
||||||
return
|
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
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
trace!("Error decoding gzip encoding");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Decoder::Deflate(ref mut decoder) => {
|
Decoder::Deflate(ref mut decoder) => {
|
||||||
|
|
Loading…
Reference in a new issue