http_response_compression/lib.rs
1//! HTTP response compression middleware for Tower.
2//!
3//! This crate provides a Tower layer that automatically compresses HTTP response
4//! bodies using Zstd, Brotli, Gzip, or Deflate based on the client's `Accept-Encoding` header.
5//!
6//! # Example
7//!
8//! ```ignore
9//! use http_response_compression::CompressionLayer;
10//! use tower::ServiceBuilder;
11//!
12//! let service = ServiceBuilder::new()
13//! .layer(CompressionLayer::new())
14//! .service(my_service);
15//! ```
16//!
17//! # Compression Rules
18//!
19//! The middleware will **not** compress responses when:
20//! - No supported `Accept-Encoding` is present in the request
21//! - `Content-Encoding` header is already set
22//! - `Content-Range` header is present (range responses)
23//! - `Content-Type` starts with `image/` (except `image/svg+xml`)
24//! - `Content-Type` starts with `application/grpc` (except `application/grpc-web`)
25//! - `Content-Length` is below the minimum size threshold (default: 860 bytes)
26//!
27//! The middleware will **always flush** after each chunk when:
28//! - `X-Accel-Buffering: no` header is present
29//! - `Content-Type` is `text/event-stream`
30//! - `Content-Type` starts with `application/grpc-web`
31//!
32//! # Response Modifications
33//!
34//! When compression is applied:
35//! - `Content-Encoding` header is set to the codec used
36//! - `Content-Length` header is removed (compressed size is unknown)
37//! - `Accept-Ranges` header is removed
38//! - `Vary` header includes `Accept-Encoding`
39
40#![deny(missing_docs)]
41
42#[cfg(not(any(
43 feature = "zstd",
44 feature = "brotli",
45 feature = "gzip",
46 feature = "deflate"
47)))]
48compile_error!("At least one compression codec feature must be enabled");
49
50mod body;
51mod codec;
52mod future;
53mod layer;
54mod service;
55
56pub use body::CompressionBody;
57pub use future::ResponseFuture;
58pub use layer::CompressionLayer;
59pub use service::CompressionService;