partially migrate to brotli crate

This commit is contained in:
Rob Ede 2021-12-22 09:27:54 +00:00
parent 1769812d0b
commit 6beb7242da
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
5 changed files with 31 additions and 21 deletions

View File

@ -109,7 +109,7 @@ url = "2.1"
actix-test = { version = "0.1.0-beta.9", features = ["openssl", "rustls"] }
awc = { version = "3.0.0-beta.14", features = ["openssl"] }
brotli2 = "0.3.2"
brotli = "3.3"
criterion = { version = "0.3", features = ["html_reports"] }
env_logger = "0.9"
flate2 = "1.0.13"
@ -142,6 +142,8 @@ actix-web-actors = { path = "actix-web-actors" }
actix-web-codegen = { path = "actix-web-codegen" }
awc = { path = "awc" }
brotli = { path = "../rust-brotli" }
# uncomment for quick testing against local actix-net repo
# actix-service = { path = "../actix-net/actix-service" }
# actix-macros = { path = "../actix-net/actix-macros" }

View File

@ -33,7 +33,7 @@ openssl = ["actix-tls/accept", "actix-tls/openssl"]
rustls = ["actix-tls/accept", "actix-tls/rustls"]
# enable compression support
compress-brotli = ["brotli2", "__compress"]
compress-brotli = ["brotli", "__compress"]
compress-gzip = ["flate2", "__compress"]
compress-zstd = ["zstd", "__compress"]
@ -75,7 +75,7 @@ smallvec = "1.6.1"
actix-tls = { version = "3.0.0-rc.1", default-features = false, optional = true }
# compression
brotli2 = { version="0.3.2", optional = true }
brotli = { version = "3.3", optional = true }
flate2 = { version = "1.0.13", optional = true }
zstd = { version = "0.9", optional = true }

View File

@ -11,9 +11,6 @@ use actix_rt::task::{spawn_blocking, JoinHandle};
use bytes::Bytes;
use futures_core::{ready, Stream};
#[cfg(feature = "compress-brotli")]
use brotli2::write::BrotliDecoder;
#[cfg(feature = "compress-gzip")]
use flate2::write::{GzDecoder, ZlibDecoder};
@ -44,9 +41,9 @@ where
pub fn new(stream: S, encoding: ContentEncoding) -> Decoder<S> {
let decoder = match encoding {
#[cfg(feature = "compress-brotli")]
ContentEncoding::Br => Some(ContentDecoder::Br(Box::new(BrotliDecoder::new(
Writer::new(),
)))),
ContentEncoding::Br => Some(ContentDecoder::Br(Box::new(
brotli::DecompressorWriter::new(Writer::new(), 8_096),
))),
#[cfg(feature = "compress-gzip")]
ContentEncoding::Deflate => Some(ContentDecoder::Deflate(Box::new(
ZlibDecoder::new(Writer::new()),
@ -160,7 +157,7 @@ enum ContentDecoder {
#[cfg(feature = "compress-gzip")]
Gzip(Box<GzDecoder<Writer>>),
#[cfg(feature = "compress-brotli")]
Br(Box<BrotliDecoder<Writer>>),
Br(Box<brotli::DecompressorWriter<Writer>>),
// We need explicit 'static lifetime here because ZstdDecoder need lifetime
// argument, and we use `spawn_blocking` in `Decoder::poll_next` that require `FnOnce() -> R + Send + 'static`
#[cfg(feature = "compress-zstd")]

View File

@ -4,6 +4,7 @@ use std::{
error::Error as StdError,
future::Future,
io::{self, Write as _},
mem,
pin::Pin,
task::{Context, Poll},
};
@ -14,9 +15,6 @@ use derive_more::Display;
use futures_core::ready;
use pin_project_lite::pin_project;
#[cfg(feature = "compress-brotli")]
use brotli2::write::BrotliEncoder;
#[cfg(feature = "compress-gzip")]
use flate2::write::{GzEncoder, ZlibEncoder};
@ -268,7 +266,7 @@ enum ContentEncoder {
Gzip(GzEncoder<Writer>),
#[cfg(feature = "compress-brotli")]
Br(BrotliEncoder<Writer>),
Br(Box<brotli::CompressorWriter<Writer>>),
// Wwe need explicit 'static lifetime here because ZstdEncoder needs a lifetime argument and we
// use `spawn_blocking` in `Encoder::poll_next` that requires `FnOnce() -> R + Send + 'static`.
@ -292,9 +290,7 @@ impl ContentEncoder {
))),
#[cfg(feature = "compress-brotli")]
ContentEncoding::Br => {
Some(ContentEncoder::Br(BrotliEncoder::new(Writer::new(), 3)))
}
ContentEncoding::Br => Some(ContentEncoder::Br(new_brotli_compressor())),
#[cfg(feature = "compress-zstd")]
ContentEncoding::Zstd => {
@ -310,7 +306,12 @@ impl ContentEncoder {
pub(crate) fn take(&mut self) -> Bytes {
match *self {
#[cfg(feature = "compress-brotli")]
ContentEncoder::Br(ref mut encoder) => encoder.get_mut().take(),
// ContentEncoder::Br(ref mut encoder) => encoder.get_mut().take(),
ContentEncoder::Br(ref mut encoder) => {
// `CompressorWriter` has no `get_mut` (yet)
let prev = mem::replace(encoder, new_brotli_compressor());
prev.into_inner().buf.freeze()
}
#[cfg(feature = "compress-gzip")]
ContentEncoder::Deflate(ref mut encoder) => encoder.get_mut().take(),
@ -326,8 +327,8 @@ impl ContentEncoder {
fn finish(self) -> Result<Bytes, io::Error> {
match self {
#[cfg(feature = "compress-brotli")]
ContentEncoder::Br(encoder) => match encoder.finish() {
Ok(writer) => Ok(writer.buf.freeze()),
ContentEncoder::Br(mut encoder) => match encoder.flush() {
Ok(()) => Ok(encoder.into_inner().buf.freeze()),
Err(err) => Err(err),
},
@ -392,6 +393,16 @@ impl ContentEncoder {
}
}
#[cfg(feature = "compress-brotli")]
fn new_brotli_compressor() -> Box<brotli::CompressorWriter<Writer>> {
Box::new(brotli::CompressorWriter::new(
Writer::new(),
8 * 1024, // 32 KiB buffer
3, // BROTLI_PARAM_QUALITY
22, // BROTLI_PARAM_LGWIN
))
}
#[derive(Debug, Display)]
#[non_exhaustive]
pub enum EncoderError {

View File

@ -101,7 +101,7 @@ actix-tls = { version = "3.0.0-rc.1", features = ["openssl", "rustls"] }
actix-utils = "3.0.0"
actix-web = { version = "4.0.0-beta.15", features = ["openssl"] }
brotli2 = "0.3.2"
brotli = "3.3"
env_logger = "0.9"
flate2 = "1.0.13"
futures-util = { version = "0.3.7", default-features = false }