From 0e21f46210ad4c4797dca8c2274f51aa36c923ba Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Thu, 28 Mar 2024 10:56:36 +0100 Subject: [PATCH] Feature gate brotli2 encoder (#321) --- .github/workflows/cov.yml | 4 ++-- .github/workflows/windows.yml | 20 +++++++++++++------- ntex/CHANGES.md | 6 ++++++ ntex/Cargo.toml | 25 ++++++++++++++----------- ntex/src/http/encoding/decoder.rs | 5 +++++ ntex/src/http/encoding/encoder.rs | 22 ++++++++++++++++++---- 6 files changed, 58 insertions(+), 24 deletions(-) diff --git a/.github/workflows/cov.yml b/.github/workflows/cov.yml index 010df083a..8b8e39887 100644 --- a/.github/workflows/cov.yml +++ b/.github/workflows/cov.yml @@ -31,10 +31,10 @@ jobs: run: cargo llvm-cov clean --workspace - name: Code coverage (glommio) - run: cargo +nightly llvm-cov --no-report --all --no-default-features --features="glommio,cookie,url,compress,openssl,rustls,ws" + run: cargo +nightly llvm-cov --no-report --all --no-default-features --features="glommio,cookie,url,compress,openssl,rustls,ws,brotli" - name: Code coverage - run: cargo +nightly llvm-cov --no-report --all --doctests --no-default-features --features="tokio,cookie,url,compress,openssl,rustls,ws" + run: cargo +nightly llvm-cov --no-report --all --doctests --no-default-features --features="tokio,cookie,url,compress,openssl,rustls,ws,brotli" - name: Generate coverage report run: cargo +nightly llvm-cov report --lcov --output-path lcov.info --ignore-filename-regex="ntex-tokio|ntex-glommio|ntex-async-std" diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index a149cf579..a990fa927 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -32,24 +32,30 @@ jobs: with: command: generate-lockfile - # - name: Cache vcpkg - # uses: actions/cache@v1 - # with: - # path: C:\vcpkg\installed\x64-windows\ - # key: x86_64-pc-windows-msvc-openssl + - name: Cache vcpkg + uses: actions/cache@v4 + with: + path: C:\vcpkg\installed\x64-windows\ + key: x86_64-pc-windows-msvc-openssl - name: Cache cargo registry - uses: actions/cache@v1 + uses: actions/cache@v4 with: path: ~/.cargo/registry key: ${{ matrix.version }}-x86_64-pc-windows-msvc-cargo-registry-trimmed-${{ hashFiles('**/Cargo.lock') }} - name: Cache cargo index - uses: actions/cache@v1 + uses: actions/cache@v4 with: path: ~/.cargo/git key: ${{ matrix.version }}-x86_64-pc-windows-msvc-cargo-index-trimmed-${{ hashFiles('**/Cargo.lock') }} + - name: Install cmake + uses: lukka/get-cmake@latest + + - name: Install nasm + uses: ilammy/setup-nasm@v1 + - name: Install OpenSSL run: | vcpkg integrate install diff --git a/ntex/CHANGES.md b/ntex/CHANGES.md index ecbf0e384..621a9381e 100644 --- a/ntex/CHANGES.md +++ b/ntex/CHANGES.md @@ -1,5 +1,11 @@ # Changes +## [1.2.1] - 2024-03-28 + +* Feature gate websocket support #320 + +* Feature gate brotli2 encoder + ## [1.2.0] - 2024-03-24 * Refactor server workers management diff --git a/ntex/Cargo.toml b/ntex/Cargo.toml index c1fabccd8..449c3d8ac 100644 --- a/ntex/Cargo.toml +++ b/ntex/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ntex" -version = "1.2.0" +version = "1.2.1" authors = ["ntex contributors "] description = "Framework for composable network services" readme = "README.md" @@ -17,14 +17,14 @@ license = "MIT OR Apache-2.0" edition = "2021" [package.metadata.docs.rs] -features = ["tokio", "openssl", "rustls", "compress", "cookie"] +features = ["tokio", "openssl", "rustls", "compress", "cookie", "ws"] [lib] name = "ntex" path = "src/lib.rs" [features] -default = [] +default = ["ws"] # openssl openssl = ["tls-openssl", "ntex-tls/openssl"] @@ -33,7 +33,7 @@ openssl = ["tls-openssl", "ntex-tls/openssl"] rustls = ["tls-rustls", "webpki-roots", "ntex-tls/rustls"] # enable compressison support -compress = ["flate2", "brotli2"] +compress = ["flate2"] # enable cookie support cookie = ["coo-kie", "coo-kie/percent-encode"] @@ -53,6 +53,9 @@ async-std = ["ntex-net/async-std"] # websocket support ws = ["dep:sha-1"] +# brotli2 support +brotli = ["dep:brotli2"] + [dependencies] ntex-codec = "0.6.2" ntex-http = "0.1.12" @@ -62,24 +65,24 @@ ntex-macros = "0.1.3" ntex-util = "1.0.1" ntex-bytes = "0.1.24" ntex-server = "1.0.0" -ntex-h2 = "0.5.1" -ntex-rt = "0.4.11" +ntex-h2 = "0.5.2" +ntex-rt = "0.4.12" ntex-io = "1.0.1" ntex-net = "1.0.0" -ntex-tls = "1.0.0" +ntex-tls = "1.1.0" base64 = "0.22" bitflags = "2" log = "0.4" -nanorand = { version = "0.7", default-features = false, features = [ - "std", - "wyrand", -] } pin-project-lite = "0.2" regex = { version = "1.10", default-features = false, features = ["std"] } serde = { version = "1.0", features = ["derive"] } sha-1 = { version = "0.10", optional = true } thiserror = "1.0" +nanorand = { version = "0.7", default-features = false, features = [ + "std", + "wyrand", +] } # http/web framework httparse = "1.8" diff --git a/ntex/src/http/encoding/decoder.rs b/ntex/src/http/encoding/decoder.rs index 12de36e11..5a5187386 100644 --- a/ntex/src/http/encoding/decoder.rs +++ b/ntex/src/http/encoding/decoder.rs @@ -1,5 +1,6 @@ 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}; @@ -26,6 +27,7 @@ where #[inline] pub fn new(stream: S, encoding: ContentEncoding) -> Decoder { let decoder = match encoding { + #[cfg(feature = "brotli")] ContentEncoding::Br => Some(ContentDecoder::Br(Box::new(BrotliDecoder::new( Writer::new(), )))), @@ -135,12 +137,14 @@ where enum ContentDecoder { Deflate(Box>), Gzip(Box>), + #[cfg(feature = "brotli")] Br(Box>), } impl ContentDecoder { fn feed_eof(&mut self) -> io::Result> { match self { + #[cfg(feature = "brotli")] ContentDecoder::Br(ref mut decoder) => match decoder.flush() { Ok(()) => { let b = decoder.get_mut().take(); @@ -179,6 +183,7 @@ impl ContentDecoder { fn feed_data(&mut self, data: Bytes) -> io::Result> { match self { + #[cfg(feature = "brotli")] ContentDecoder::Br(ref mut decoder) => match decoder.write_all(&data) { Ok(_) => { decoder.flush()?; diff --git a/ntex/src/http/encoding/encoder.rs b/ntex/src/http/encoding/encoder.rs index 7678a5536..92003e607 100644 --- a/ntex/src/http/encoding/encoder.rs +++ b/ntex/src/http/encoding/encoder.rs @@ -1,6 +1,7 @@ //! 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}; @@ -190,15 +191,23 @@ fn update_head(encoding: ContentEncoding, head: &mut ResponseHead) { enum ContentEncoder { Deflate(ZlibEncoder), Gzip(GzEncoder), + #[cfg(feature = "brotli")] Br(BrotliEncoder), } impl ContentEncoder { fn can_encode(encoding: ContentEncoding) -> bool { - matches!( - encoding, - ContentEncoding::Deflate | ContentEncoding::Gzip | ContentEncoding::Br - ) + #[cfg(feature = "brotli")] + { + matches!( + encoding, + ContentEncoding::Deflate | ContentEncoding::Gzip | ContentEncoding::Br + ) + } + #[cfg(not(feature = "brotli"))] + { + matches!(encoding, ContentEncoding::Deflate | ContentEncoding::Gzip) + } } fn encoder(encoding: ContentEncoding) -> Option { @@ -211,6 +220,7 @@ impl ContentEncoder { Writer::new(), flate2::Compression::fast(), ))), + #[cfg(feature = "brotli")] ContentEncoding::Br => { Some(ContentEncoder::Br(BrotliEncoder::new(Writer::new(), 3))) } @@ -220,6 +230,7 @@ impl ContentEncoder { 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(), @@ -228,6 +239,7 @@ impl ContentEncoder { fn finish(self) -> Result { match self { + #[cfg(feature = "brotli")] ContentEncoder::Br(encoder) => match encoder.finish() { Ok(writer) => Ok(writer.buf.freeze()), Err(err) => Err(err), @@ -245,6 +257,7 @@ 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) => { @@ -275,6 +288,7 @@ 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"), } }