Remove brotli support (#531)

This commit is contained in:
Nikolay Kim 2025-03-16 12:38:09 +01:00 committed by GitHub
parent 7417ee3a4b
commit 5426790eb0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 21 additions and 471 deletions

View file

@ -12,7 +12,7 @@ jobs:
with:
toolchain: stable
- run:
cargo check --tests --all --no-default-features --features="ntex/compio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws,ntex/brotli"
cargo check --tests --all --no-default-features --features="ntex/compio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws"
clippy:
name: Clippy
@ -24,7 +24,7 @@ jobs:
toolchain: stable
components: clippy
- run:
cargo clippy --tests --all --no-default-features --features="ntex/compio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws,ntex/brotli"
cargo clippy --tests --all --no-default-features --features="ntex/compio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws"
fmt:
name: Rustfmt

View file

@ -27,16 +27,16 @@ jobs:
run: cargo llvm-cov clean --workspace
- name: Code coverage (tokio)
run: cargo llvm-cov --no-report --all --no-default-features --features="ntex/tokio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws,ntex/brotli"
run: cargo llvm-cov --no-report --all --no-default-features --features="ntex/tokio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws"
- name: Code coverage (compio)
run: cargo llvm-cov --no-report --all --no-default-features --features="ntex/compio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws,ntex/brotli"
run: cargo llvm-cov --no-report --all --no-default-features --features="ntex/compio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws"
- name: Code coverage (neon)
run: cargo llvm-cov --no-report --all --no-default-features --features="ntex/neon,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws,ntex/brotli"
run: cargo llvm-cov --no-report --all --no-default-features --features="ntex/neon,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws"
- name: Code coverage (neon-uring)
run: cargo llvm-cov --no-report --all --no-default-features --features="ntex/neon-uring,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws,ntex/brotli"
run: cargo llvm-cov --no-report --all --no-default-features --features="ntex/neon-uring,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws"
- name: Generate coverage report
run: cargo llvm-cov report --lcov --output-path lcov.info --ignore-filename-regex="ntex-compio|ntex-tokio"

View file

@ -47,22 +47,22 @@ jobs:
- name: Run tests (tokio)
timeout-minutes: 40
run: |
cargo test --all --no-fail-fast --no-default-features --features="ntex/tokio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws,ntex/brotli"
cargo test --all --no-fail-fast --no-default-features --features="ntex/tokio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws"
- name: Run tests (compio)
timeout-minutes: 40
run: |
cargo test --all --no-default-features --features="ntex/compio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws,ntex/brotli"
cargo test --all --no-default-features --features="ntex/compio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws"
- name: Run tests (neon)
timeout-minutes: 40
run: |
cargo test --all --no-default-features --features="ntex/neon,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws,ntex/brotli"
cargo test --all --no-default-features --features="ntex/neon,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws"
- name: Run tests (neon-uring)
timeout-minutes: 40
run: |
cargo test --all --no-default-features --features="ntex/neon-uring,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws,ntex/brotli"
cargo test --all --no-default-features --features="ntex/neon-uring,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws"
- name: Install cargo-cache
continue-on-error: true

View file

@ -38,15 +38,15 @@ jobs:
key: ${{ matrix.version }}-aarch64-apple-darwin-cargo-index-trimmed-${{ hashFiles('**/Cargo.lock') }}
- name: Run tests (tokio)
run: cargo test --all --no-default-features --no-fail-fast --features="ntex/tokio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws,ntex/brotli"
run: cargo test --all --no-default-features --no-fail-fast --features="ntex/tokio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws"
- name: Run tests (compio)
timeout-minutes: 40
run: cargo test --all --no-default-features --no-fail-fast --features="ntex/compio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws,ntex/brotli"
run: cargo test --all --no-default-features --no-fail-fast --features="ntex/compio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws"
- name: Run tests (neon)
timeout-minutes: 40
run: cargo test --all --no-default-features --no-fail-fast --features="ntex/neon,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws,ntex/brotli"
run: cargo test --all --no-default-features --no-fail-fast --features="ntex/neon,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws"
- name: Install cargo-cache
continue-on-error: true

View file

@ -63,8 +63,8 @@ jobs:
- name: Run tests (tokio)
run: |
cargo test --all --lib --no-default-features --no-fail-fast --features="ntex/tokio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws,ntex/brotli" -- --skip test_timer
cargo test --all --lib --no-default-features --no-fail-fast --features="ntex/tokio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws" -- --skip test_timer
- name: Run tests (compio)
run: |
cargo test --all --lib --no-default-features --no-fail-fast --features="ntex/compio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws,ntex/brotli" -- --skip test_timer
cargo test --all --lib --no-default-features --no-fail-fast --features="ntex/compio,ntex/cookie,ntex/url,ntex/compress,ntex/openssl,ntex/rustls,ntex/ws" -- --skip test_timer

View file

@ -4,6 +4,8 @@
* http: Allow to run publish future to completion in case error
* http: Remove brotli support
## [2.12.1] - 2025-03-14
* Allow to disable test logging (no-test-logging features)

View file

@ -18,7 +18,7 @@ edition = "2021"
rust-version = "1.75"
[package.metadata.docs.rs]
features = ["tokio", "openssl", "rustls", "compress", "cookie", "ws", "brotli", "ntex-tls/rustls-ring"]
features = ["tokio", "openssl", "rustls", "compress", "cookie", "ws", "ntex-tls/rustls-ring"]
[lib]
name = "ntex"
@ -57,9 +57,6 @@ neon-uring = ["ntex-net/neon", "ntex-net/io-uring"]
# websocket support
ws = ["dep:sha-1"]
# brotli2 support
brotli = ["dep:brotli2"]
# disable [ntex::test] logging configuration
no-test-logging = []
@ -112,7 +109,6 @@ tls-rustls = { version = "0.23", package = "rustls", optional = true, default-fe
webpki-roots = { version = "0.26", optional = true }
# compression
brotli2 = { version = "0.3.2", optional = true }
flate2 = { version = "1.0", optional = true }
[dev-dependencies]

View file

@ -1,7 +1,5 @@
use std::{future::Future, io, io::Write, pin::Pin, task::Context, task::Poll};
#[cfg(feature = "brotli")]
use brotli2::write::BrotliDecoder;
use flate2::write::{GzDecoder, ZlibDecoder};
use super::Writer;
@ -27,10 +25,6 @@ where
#[inline]
pub fn new(stream: S, encoding: ContentEncoding) -> Decoder<S> {
let decoder = match encoding {
#[cfg(feature = "brotli")]
ContentEncoding::Br => Some(ContentDecoder::Br(Box::new(BrotliDecoder::new(
Writer::new(),
)))),
ContentEncoding::Deflate => Some(ContentDecoder::Deflate(Box::new(
ZlibDecoder::new(Writer::new()),
))),
@ -137,25 +131,11 @@ where
enum ContentDecoder {
Deflate(Box<ZlibDecoder<Writer>>),
Gzip(Box<GzDecoder<Writer>>),
#[cfg(feature = "brotli")]
Br(Box<BrotliDecoder<Writer>>),
}
impl ContentDecoder {
fn feed_eof(&mut self) -> io::Result<Option<Bytes>> {
match self {
#[cfg(feature = "brotli")]
ContentDecoder::Br(ref mut decoder) => match decoder.flush() {
Ok(()) => {
let b = decoder.get_mut().take();
if !b.is_empty() {
Ok(Some(b))
} else {
Ok(None)
}
}
Err(e) => Err(e),
},
ContentDecoder::Gzip(ref mut decoder) => match decoder.try_finish() {
Ok(_) => {
let b = decoder.get_mut().take();
@ -183,19 +163,6 @@ impl ContentDecoder {
fn feed_data(&mut self, data: Bytes) -> io::Result<Option<Bytes>> {
match self {
#[cfg(feature = "brotli")]
ContentDecoder::Br(ref mut decoder) => match decoder.write_all(&data) {
Ok(_) => {
decoder.flush()?;
let b = decoder.get_mut().take();
if !b.is_empty() {
Ok(Some(b))
} else {
Ok(None)
}
}
Err(e) => Err(e),
},
ContentDecoder::Gzip(ref mut decoder) => match decoder.write_all(&data) {
Ok(_) => {
decoder.flush()?;

View file

@ -1,8 +1,6 @@
//! Stream encoder
use std::{fmt, future::Future, io, io::Write, pin::Pin, task::Context, task::Poll};
#[cfg(feature = "brotli")]
use brotli2::write::BrotliEncoder;
use flate2::write::{GzEncoder, ZlibEncoder};
use crate::http::body::{Body, BodySize, MessageBody, ResponseBody};
@ -191,23 +189,11 @@ fn update_head(encoding: ContentEncoding, head: &mut ResponseHead) {
enum ContentEncoder {
Deflate(ZlibEncoder<Writer>),
Gzip(GzEncoder<Writer>),
#[cfg(feature = "brotli")]
Br(BrotliEncoder<Writer>),
}
impl ContentEncoder {
fn can_encode(encoding: ContentEncoding) -> bool {
#[cfg(feature = "brotli")]
{
matches!(
encoding,
ContentEncoding::Deflate | ContentEncoding::Gzip | ContentEncoding::Br
)
}
#[cfg(not(feature = "brotli"))]
{
matches!(encoding, ContentEncoding::Deflate | ContentEncoding::Gzip)
}
matches!(encoding, ContentEncoding::Deflate | ContentEncoding::Gzip)
}
fn encoder(encoding: ContentEncoding) -> Option<Self> {
@ -220,18 +206,12 @@ impl ContentEncoder {
Writer::new(),
flate2::Compression::fast(),
))),
#[cfg(feature = "brotli")]
ContentEncoding::Br => {
Some(ContentEncoder::Br(BrotliEncoder::new(Writer::new(), 3)))
}
_ => None,
}
}
fn take(&mut self) -> Bytes {
match *self {
#[cfg(feature = "brotli")]
ContentEncoder::Br(ref mut encoder) => encoder.get_mut().take(),
ContentEncoder::Deflate(ref mut encoder) => encoder.get_mut().take(),
ContentEncoder::Gzip(ref mut encoder) => encoder.get_mut().take(),
}
@ -239,11 +219,6 @@ impl ContentEncoder {
fn finish(self) -> Result<Bytes, io::Error> {
match self {
#[cfg(feature = "brotli")]
ContentEncoder::Br(encoder) => match encoder.finish() {
Ok(writer) => Ok(writer.buf.freeze()),
Err(err) => Err(err),
},
ContentEncoder::Gzip(encoder) => match encoder.finish() {
Ok(writer) => Ok(writer.buf.freeze()),
Err(err) => Err(err),
@ -257,14 +232,6 @@ impl ContentEncoder {
fn write(&mut self, data: &[u8]) -> Result<(), io::Error> {
match *self {
#[cfg(feature = "brotli")]
ContentEncoder::Br(ref mut encoder) => match encoder.write_all(data) {
Ok(_) => Ok(()),
Err(err) => {
log::trace!("Error decoding br encoding: {}", err);
Err(err)
}
},
ContentEncoder::Gzip(ref mut encoder) => match encoder.write_all(data) {
Ok(_) => Ok(()),
Err(err) => {
@ -288,8 +255,6 @@ impl fmt::Debug for ContentEncoder {
match self {
ContentEncoder::Deflate(_) => write!(f, "ContentEncoder::Deflate"),
ContentEncoder::Gzip(_) => write!(f, "ContentEncoder::Gzip"),
#[cfg(feature = "brotli")]
ContentEncoder::Br(_) => write!(f, "ContentEncoder::Br"),
}
}
}

View file

@ -3,16 +3,14 @@ use std::io::{Read, Write};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use brotli2::write::BrotliEncoder;
use coo_kie::Cookie;
use flate2::{read::GzDecoder, write::GzEncoder, write::ZlibEncoder, Compression};
use futures_util::stream::once;
use rand::Rng;
use ntex::http::client::error::{JsonPayloadError, SendRequestError};
use ntex::http::client::error::SendRequestError;
use ntex::http::client::{Client, Connector};
use ntex::http::test::server as test_server;
use ntex::http::{header, HttpMessage, HttpService, Method};
use ntex::http::{header, HttpMessage, HttpService};
use ntex::service::{chain_factory, map_config};
use ntex::web::dev::AppConfig;
use ntex::web::middleware::Compress;
@ -534,126 +532,6 @@ async fn test_client_gzip_encoding_large_random() {
assert_eq!(bytes, Bytes::from(data));
}
#[ntex::test]
async fn test_client_brotli_encoding() {
let srv = test::server(|| {
App::new().service(web::resource("/").route(web::to(|data: Bytes| async move {
let mut e = BrotliEncoder::new(Vec::new(), 5);
e.write_all(&data).unwrap();
let data = e.finish().unwrap();
HttpResponse::Ok()
.header("content-encoding", "br")
.body(data)
})))
});
// client request
let mut response = srv.post("/").send_body(STR).await.unwrap();
assert!(response.status().is_success());
// read response
let bytes = response.body().await.unwrap();
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}
#[ntex::test]
async fn test_client_brotli_encoding_large_random() {
let data = rand::thread_rng()
.sample_iter(&rand::distributions::Alphanumeric)
.take(70_000)
.map(char::from)
.collect::<String>();
let srv = test::server(|| {
App::new().service(web::resource("/").route(web::to(|data: Bytes| async move {
let mut e = BrotliEncoder::new(Vec::new(), 5);
e.write_all(&data).unwrap();
let data = e.finish().unwrap();
HttpResponse::Ok()
.header("content-encoding", "br")
.body(data)
})))
});
// client request
let mut response = srv.post("/").send_body(data.clone()).await.unwrap();
assert!(response.status().is_success());
// read response
let bytes = response.body().await.unwrap();
assert_eq!(bytes.len(), data.len());
assert_eq!(bytes, Bytes::from(data.clone()));
// frozen request
let request = srv.post("/").timeout(Seconds(30)).freeze().unwrap();
assert_eq!(request.get_method(), Method::POST);
assert_eq!(request.get_uri(), srv.url("/").as_str());
let mut response = request.send_body(data.clone()).await.unwrap();
assert!(response.status().is_success());
// read response
let bytes = response.body().await.unwrap();
assert_eq!(bytes.len(), data.len());
assert_eq!(bytes, Bytes::from(data.clone()));
// extra header
let mut response = request
.extra_header("x-test2", "222")
.send_body(data.clone())
.await
.unwrap();
assert!(response.status().is_success());
// read response
let bytes = response.body().await.unwrap();
assert_eq!(bytes.len(), data.len());
assert_eq!(bytes, Bytes::from(data.clone()));
// client stream request
let mut response = srv
.post("/")
.send_stream(once(Ready::Ok::<_, JsonPayloadError>(Bytes::from(
data.clone(),
))))
.await
.unwrap();
assert!(response.status().is_success());
// read response
let bytes = response.body().await.unwrap();
assert_eq!(bytes.len(), data.len());
assert_eq!(bytes, Bytes::from(data.clone()));
// frozen request
let request = srv.post("/").timeout(Seconds(30)).freeze().unwrap();
let mut response = request
.send_stream(once(Ready::Ok::<_, JsonPayloadError>(Bytes::from(
data.clone(),
))))
.await
.unwrap();
assert!(response.status().is_success());
// read response
let bytes = response.body().await.unwrap();
assert_eq!(bytes.len(), data.len());
assert_eq!(bytes, Bytes::from(data.clone()));
let mut response = request
.extra_header("x-test2", "222")
.send_stream(once(Ready::Ok::<_, JsonPayloadError>(Bytes::from(
data.clone(),
))))
.await
.unwrap();
assert!(response.status().is_success());
// read response
let bytes = response.body().await.unwrap();
assert_eq!(bytes.len(), data.len());
assert_eq!(bytes, Bytes::from(data.clone()));
}
#[ntex::test]
async fn test_client_deflate_encoding() {
let srv = test::server(|| {

View file

@ -1,6 +1,5 @@
use std::{future::Future, io, io::Read, io::Write, pin::Pin, task::Context, task::Poll};
use brotli2::write::{BrotliDecoder, BrotliEncoder};
use flate2::read::GzDecoder;
use flate2::write::{GzEncoder, ZlibDecoder, ZlibEncoder};
use flate2::Compression;
@ -318,36 +317,6 @@ async fn test_body_chunked_implicit() {
assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref()));
}
#[ntex::test]
async fn test_body_br_streaming() {
let srv = test::server_with(test::config().h1(), || {
App::new().wrap(Compress::new(ContentEncoding::Br)).service(
web::resource("/").route(web::to(move || async {
HttpResponse::Ok()
.streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24))
})),
)
});
let mut response = srv
.get("/")
.header(ACCEPT_ENCODING, "br")
.no_decompress()
.send()
.await
.unwrap();
assert!(response.status().is_success());
// read response
let bytes = response.body().await.unwrap();
// decode br
let mut e = BrotliDecoder::new(Vec::with_capacity(2048));
e.write_all(bytes.as_ref()).unwrap();
let dec = e.finish().unwrap();
assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref()));
}
#[ntex::test]
async fn test_head_binary() {
let srv = test::server_with(test::config().h1(), || {
@ -422,35 +391,6 @@ async fn test_body_deflate() {
assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref()));
}
#[ntex::test]
async fn test_body_brotli() {
let srv = test::server_with(test::config().h1(), || {
App::new().wrap(Compress::new(ContentEncoding::Br)).service(
web::resource("/")
.route(web::to(move || async { HttpResponse::Ok().body(STR) })),
)
});
// client request
let mut response = srv
.get("/")
.header(ACCEPT_ENCODING, "br")
.no_decompress()
.send()
.await
.unwrap();
assert!(response.status().is_success());
// read response
let bytes = response.body().await.unwrap();
// decode brotli
let mut e = BrotliDecoder::new(Vec::with_capacity(2048));
e.write_all(bytes.as_ref()).unwrap();
let dec = e.finish().unwrap();
assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref()));
}
#[ntex::test]
async fn test_encoding() {
let srv = test::server_with(test::config().h1(), || {
@ -644,204 +584,6 @@ async fn test_reading_deflate_encoding_large_random() {
assert_eq!(bytes, Bytes::from(data));
}
#[ntex::test]
async fn test_brotli_encoding() {
let srv = test::server_with(test::config().h1(), || {
App::new().service(web::resource("/").route(web::to(move |body: Bytes| async {
HttpResponse::Ok().body(body)
})))
});
let mut e = BrotliEncoder::new(Vec::new(), 5);
e.write_all(STR.as_ref()).unwrap();
let enc = e.finish().unwrap();
// client request
let request = srv
.post("/")
.header(CONTENT_ENCODING, "br")
.send_body(enc.clone());
let mut response = request.await.unwrap();
assert!(response.status().is_success());
// read response
let bytes = response.body().await.unwrap();
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}
#[ntex::test]
async fn test_brotli_encoding_large() {
let data = rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(320_000)
.map(char::from)
.collect::<String>();
let srv = test::server_with(test::config().h1(), || {
App::new().service(
web::resource("/")
.state(web::types::PayloadConfig::new(320_000))
.route(web::to(move |body: Bytes| async {
HttpResponse::Ok().streaming(TestBody::new(body, 10240))
})),
)
});
let mut e = BrotliEncoder::new(Vec::new(), 5);
e.write_all(data.as_ref()).unwrap();
let enc = e.finish().unwrap();
// client request
let request = srv
.post("/")
.header(CONTENT_ENCODING, "br")
.send_body(enc.clone());
let mut response = request.await.unwrap();
assert!(response.status().is_success());
// read response
let bytes = response.body().limit(320_000).await.unwrap();
assert_eq!(bytes, Bytes::from(data));
}
#[cfg(feature = "openssl")]
#[ntex::test]
async fn test_brotli_encoding_large_openssl() {
// load ssl keys
use tls_openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
builder
.set_private_key_file("./tests/key.pem", SslFiletype::PEM)
.unwrap();
builder
.set_certificate_chain_file("./tests/cert.pem")
.unwrap();
let data = STR.repeat(10);
let srv = test::server_with(test::config().openssl(builder.build()), move || {
App::new().service(web::resource("/").route(web::to(|bytes: Bytes| async {
HttpResponse::Ok()
.encoding(ContentEncoding::Identity)
.body(bytes)
})))
});
// body
let mut e = BrotliEncoder::new(Vec::new(), 3);
e.write_all(data.as_ref()).unwrap();
let enc = e.finish().unwrap();
// client request
let mut response = srv
.post("/")
.header(CONTENT_ENCODING, "br")
.send_body(enc)
.await
.unwrap();
assert!(response.status().is_success());
// read response
let bytes = response.body().await.unwrap();
assert_eq!(bytes, Bytes::from(data));
}
#[cfg(feature = "openssl")]
#[ntex::test]
async fn test_brotli_encoding_large_openssl_h1() {
// load ssl keys
use tls_openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
builder
.set_private_key_file("./tests/key.pem", SslFiletype::PEM)
.unwrap();
builder
.set_certificate_chain_file("./tests/cert.pem")
.unwrap();
let data = STR.repeat(10);
let srv = test::server_with(test::config().openssl(builder.build()).h1(), move || {
App::new().service(web::resource("/").route(web::to(|bytes: Bytes| async {
HttpResponse::Ok()
.encoding(ContentEncoding::Identity)
.body(bytes)
})))
});
// body
let mut e = BrotliEncoder::new(Vec::new(), 3);
e.write_all(data.as_ref()).unwrap();
let enc = e.finish().unwrap();
// client request
let mut response = srv
.post("/")
.header(CONTENT_ENCODING, "br")
.send_body(enc)
.await
.unwrap();
assert!(response.status().is_success());
// read response
let bytes = response.body().await.unwrap();
assert_eq!(bytes, Bytes::from(data));
}
#[cfg(feature = "openssl")]
#[ntex::test]
async fn test_brotli_encoding_large_openssl_h2() {
// load ssl keys
use tls_openssl::ssl::{AlpnError, SslAcceptor, SslFiletype, SslMethod};
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
builder
.set_private_key_file("./tests/key.pem", SslFiletype::PEM)
.unwrap();
builder
.set_certificate_chain_file("./tests/cert.pem")
.unwrap();
builder.set_alpn_select_callback(|_, protos| {
const H2: &[u8] = b"\x02h2";
const H11: &[u8] = b"\x08http/1.1";
if protos.windows(3).any(|window| window == H2) {
Ok(b"h2")
} else if protos.windows(9).any(|window| window == H11) {
Ok(b"http/1.1")
} else {
Err(AlpnError::NOACK)
}
});
builder.set_alpn_protos(b"\x08http/1.1\x02h2").unwrap();
let data = STR.repeat(10);
let srv = test::server_with(test::config().openssl(builder.build()).h2(), move || {
App::new().service(web::resource("/").route(web::to(|bytes: Bytes| async {
HttpResponse::Ok()
.encoding(ContentEncoding::Identity)
.body(bytes)
})))
});
// body
let mut e = BrotliEncoder::new(Vec::new(), 3);
e.write_all(data.as_ref()).unwrap();
let enc = e.finish().unwrap();
// client request
let mut response = srv
.post("/")
.header(CONTENT_ENCODING, "br")
.send_body(enc)
.await
.unwrap();
assert!(response.status().is_success());
// read response
let bytes = response.body().await.unwrap();
assert_eq!(bytes, Bytes::from(data));
}
#[cfg(all(feature = "rustls", feature = "openssl"))]
#[ntex::test]
async fn test_reading_deflate_encoding_large_random_rustls() {