diff --git a/Cargo.toml b/Cargo.toml index d796548e..68959fab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -115,7 +115,7 @@ actix-http = { version = "2.1.0", features = ["actors"] } rand = "0.7" env_logger = "0.8" serde_derive = "1.0" -brotli2 = "0.3.2" +brotli = "3.3.3" flate2 = "1.0.13" criterion = "0.3" diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 5debd5d4..50bfa38b 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -31,7 +31,7 @@ openssl = ["actix-tls/openssl", "actix-connect/openssl"] rustls = ["actix-tls/rustls", "actix-connect/rustls"] # enable compressison support -compress = ["flate2", "brotli2"] +compress = ["flate2", "brotli"] # support for secure cookies secure-cookies = ["cookie/secure"] @@ -82,7 +82,7 @@ serde_urlencoded = "0.7" time = { version = "0.2.7", default-features = false, features = ["std"] } # compression -brotli2 = { version="0.3.2", optional = true } +brotli = { version = "3.3.3", optional = true } flate2 = { version = "1.0.13", optional = true } [dev-dependencies] diff --git a/actix-http/src/encoding/decoder.rs b/actix-http/src/encoding/decoder.rs index b6043585..53cb2405 100644 --- a/actix-http/src/encoding/decoder.rs +++ b/actix-http/src/encoding/decoder.rs @@ -4,7 +4,7 @@ use std::pin::Pin; use std::task::{Context, Poll}; use actix_threadpool::{run, CpuFuture}; -use brotli2::write::BrotliDecoder; +use brotli::DecompressorWriter as BrotliDecoder; use bytes::Bytes; use flate2::write::{GzDecoder, ZlibDecoder}; use futures_core::{ready, Stream}; @@ -31,7 +31,7 @@ where pub fn new(stream: S, encoding: ContentEncoding) -> Decoder { let decoder = match encoding { ContentEncoding::Br => Some(ContentDecoder::Br(Box::new( - BrotliDecoder::new(Writer::new()), + BrotliDecoder::new(Writer::new(), 8 * 1024), ))), ContentEncoding::Deflate => Some(ContentDecoder::Deflate(Box::new( ZlibDecoder::new(Writer::new()), diff --git a/actix-http/src/encoding/encoder.rs b/actix-http/src/encoding/encoder.rs index eb182128..0b75302d 100644 --- a/actix-http/src/encoding/encoder.rs +++ b/actix-http/src/encoding/encoder.rs @@ -5,7 +5,7 @@ use std::pin::Pin; use std::task::{Context, Poll}; use actix_threadpool::{run, CpuFuture}; -use brotli2::write::BrotliEncoder; +use brotli::CompressorWriter as BrotliEncoder; use bytes::Bytes; use flate2::write::{GzEncoder, ZlibEncoder}; use futures_core::ready; @@ -212,9 +212,12 @@ impl ContentEncoder { Writer::new(), flate2::Compression::fast(), ))), - ContentEncoding::Br => { - Some(ContentEncoder::Br(BrotliEncoder::new(Writer::new(), 3))) - } + ContentEncoding::Br => Some(ContentEncoder::Br(BrotliEncoder::new( + Writer::new(), + 32 * 1024, + 3, + 22, + ))), _ => None, } } @@ -230,8 +233,8 @@ impl ContentEncoder { fn finish(self) -> Result { match self { - 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), }, ContentEncoder::Gzip(encoder) => match encoder.finish() { diff --git a/awc/Cargo.toml b/awc/Cargo.toml index 3c1963d6..c14e200c 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -65,7 +65,7 @@ actix-http-test = { version = "2.0.0", features = ["openssl"] } actix-utils = "2.0.0" actix-server = "1.0.0" actix-tls = { version = "2.0.0", features = ["openssl", "rustls"] } -brotli2 = "0.3.2" +brotli = "3.3.3" flate2 = "1.0.13" futures-util = { version = "0.3.5", default-features = false } env_logger = "0.7" diff --git a/awc/tests/test_client.rs b/awc/tests/test_client.rs index a9552d0d..014d6989 100644 --- a/awc/tests/test_client.rs +++ b/awc/tests/test_client.rs @@ -4,7 +4,7 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; use std::time::Duration; -use brotli2::write::BrotliEncoder; +use brotli::CompressorWriter as BrotliEncoder; use bytes::Bytes; use flate2::read::GzDecoder; use flate2::write::GzEncoder; @@ -506,9 +506,10 @@ async fn test_client_gzip_encoding_large_random() { async fn test_client_brotli_encoding() { let srv = test::start(|| { App::new().service(web::resource("/").route(web::to(|data: Bytes| { - let mut e = BrotliEncoder::new(Vec::new(), 5); + let mut e = BrotliEncoder::new(Vec::new(), 8096, 5, 22); e.write_all(&data).unwrap(); - let data = e.finish().unwrap(); + e.flush().unwrap(); + let data = e.into_inner(); HttpResponse::Ok() .header("content-encoding", "br") .body(data) @@ -533,9 +534,9 @@ async fn test_client_brotli_encoding_large_random() { let srv = test::start(|| { App::new().service(web::resource("/").route(web::to(|data: Bytes| { - let mut e = BrotliEncoder::new(Vec::new(), 5); + let mut e = BrotliEncoder::new(Vec::new(), 8096, 5, 22); e.write_all(&data).unwrap(); - let data = e.finish().unwrap(); + let data = e.into_inner(); HttpResponse::Ok() .header("content-encoding", "br") .body(data) diff --git a/tests/test_server.rs b/tests/test_server.rs index f8a9ab86..60b12a4b 100644 --- a/tests/test_server.rs +++ b/tests/test_server.rs @@ -7,7 +7,8 @@ use actix_http::http::header::{ ContentEncoding, ACCEPT_ENCODING, CONTENT_ENCODING, CONTENT_LENGTH, TRANSFER_ENCODING, }; -use brotli2::write::{BrotliDecoder, BrotliEncoder}; + +use brotli::{CompressorWriter as BrotliEncoder, DecompressorWriter as BrotliDecoder}; use bytes::Bytes; use flate2::read::GzDecoder; use flate2::write::{GzEncoder, ZlibDecoder, ZlibEncoder}; @@ -340,9 +341,9 @@ async fn test_body_br_streaming() { println!("TEST: {:?}", bytes.len()); // decode br - let mut e = BrotliDecoder::new(Vec::with_capacity(2048)); + let mut e = BrotliDecoder::new(Vec::with_capacity(2048), 8096); e.write_all(bytes.as_ref()).unwrap(); - let dec = e.finish().unwrap(); + let dec = e.into_inner().unwrap(); println!("T: {:?}", Bytes::copy_from_slice(&dec)); assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); } @@ -439,9 +440,9 @@ async fn test_body_brotli() { let bytes = response.body().await.unwrap(); // decode brotli - let mut e = BrotliDecoder::new(Vec::with_capacity(2048)); + let mut e = BrotliDecoder::new(Vec::with_capacity(2048), 8096); e.write_all(bytes.as_ref()).unwrap(); - let dec = e.finish().unwrap(); + let dec = e.into_inner().unwrap(); assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); } @@ -650,9 +651,10 @@ async fn test_brotli_encoding() { ) }); - let mut e = BrotliEncoder::new(Vec::new(), 5); + let mut e = BrotliEncoder::new(Vec::new(), 8096, 5, 22); e.write_all(STR.as_ref()).unwrap(); - let enc = e.finish().unwrap(); + e.flush().unwrap(); + let enc = e.into_inner(); // client request let request = srv @@ -684,9 +686,10 @@ async fn test_brotli_encoding_large() { ) }); - let mut e = BrotliEncoder::new(Vec::new(), 5); + let mut e = BrotliEncoder::new(Vec::new(), 8096, 5, 22); e.write_all(data.as_ref()).unwrap(); - let enc = e.finish().unwrap(); + e.flush().unwrap(); + let enc = e.into_inner(); // client request let request = srv @@ -724,9 +727,9 @@ async fn test_brotli_encoding_large_openssl() { }); // body - let mut e = BrotliEncoder::new(Vec::new(), 3); + let mut e = BrotliEncoder::new(Vec::new(), 8096, 5, 22); e.write_all(data.as_ref()).unwrap(); - let enc = e.finish().unwrap(); + let enc = e.into_inner(); // client request let mut response = srv