Enable brotli compression for API and static files
- Add compression-br feature to tower-http - Apply CompressionLayer to API routes (JSON responses) - Apply CompressionLayer to static files (CSS, JS, locales) - File downloads remain uncompressed (avoid double compression)
This commit is contained in:
Generated
+37
@@ -28,6 +28,21 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "alloc-no-stdlib"
|
||||
version = "2.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"
|
||||
|
||||
[[package]]
|
||||
name = "alloc-stdlib"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
|
||||
dependencies = [
|
||||
"alloc-no-stdlib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.21"
|
||||
@@ -263,6 +278,27 @@ dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "brotli"
|
||||
version = "8.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560"
|
||||
dependencies = [
|
||||
"alloc-no-stdlib",
|
||||
"alloc-stdlib",
|
||||
"brotli-decompressor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "brotli-decompressor"
|
||||
version = "5.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03"
|
||||
dependencies = [
|
||||
"alloc-no-stdlib",
|
||||
"alloc-stdlib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.19.1"
|
||||
@@ -362,6 +398,7 @@ version = "0.4.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00828ba6fd27b45a448e57dbfe84f1029d4c9f26b368157e9a448a5f49a2ec2a"
|
||||
dependencies = [
|
||||
"brotli",
|
||||
"compression-core",
|
||||
"flate2",
|
||||
"memchr",
|
||||
|
||||
+1
-2
@@ -13,7 +13,7 @@ tokio-stream = { version = "0.1.18", features = ["fs"] }
|
||||
bytes = "1.11.1"
|
||||
tempfile = "3.25.0"
|
||||
tower = "0.5.3"
|
||||
tower-http = { version = "0.6.8", features = ["fs", "compression-gzip", "trace", "cors", "add-extension", "request-id", "set-header"] }
|
||||
tower-http = { version = "0.6.8", features = ["fs", "compression-gzip", "compression-br", "trace", "cors", "add-extension", "request-id", "set-header"] }
|
||||
flate2 = "1.1.9"
|
||||
zip = "=6.0.0"
|
||||
tracing = "0.1.44"
|
||||
@@ -75,4 +75,3 @@ debug = true
|
||||
lto = "fat"
|
||||
codegen-units = 1
|
||||
opt-level = 3
|
||||
|
||||
|
||||
@@ -358,7 +358,8 @@ pub fn create_api_routes(app_state: &AppState) -> Router<AppState> {
|
||||
let admin_router = admin_handler::admin_routes().with_state(app_state.clone());
|
||||
router = router.nest("/admin", admin_router);
|
||||
|
||||
// Compression for API responses (JSON) — excludes file downloads
|
||||
router
|
||||
.layer(CompressionLayer::new())
|
||||
.layer(CompressionLayer::new().br(true).gzip(true))
|
||||
.layer(TraceLayer::new_for_http())
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ pub fn create_web_routes() -> Router<AppState> {
|
||||
let static_path = config.static_path.clone();
|
||||
|
||||
// Static assets (JS, CSS, JSON, SVG, ICO) served via ServeDir
|
||||
// with gzip compression and aggressive caching (7 days).
|
||||
// with brotli + gzip compression and aggressive caching (7 days).
|
||||
// HTML pages are served via explicit routes (include_str!) and
|
||||
// do NOT pass through these layers.
|
||||
let static_service = ServeDir::new(static_path);
|
||||
@@ -26,7 +26,7 @@ pub fn create_web_routes() -> Router<AppState> {
|
||||
.route("/shared", get(serve_shared_page))
|
||||
// Serve static files with compression + cache headers
|
||||
.fallback_service(static_service)
|
||||
.layer(CompressionLayer::new())
|
||||
.layer(CompressionLayer::new().br(true).gzip(true))
|
||||
.layer(SetResponseHeaderLayer::if_not_present(
|
||||
CACHE_CONTROL,
|
||||
HeaderValue::from_static("public, max-age=604800, stale-while-revalidate=86400"),
|
||||
|
||||
Reference in New Issue
Block a user