From 42b242204c8d265007b7e6f177413653abbed959 Mon Sep 17 00:00:00 2001 From: Dionisio Date: Fri, 6 Mar 2026 22:59:48 +0100 Subject: [PATCH] perf: enable HTTP compression (gzip + Brotli) with smart predicate - Apply CompressionLayer globally with content-type filtering - Compress: JSON, XML, HTML, CSS, JS (60-80% bandwidth savings) - Skip: images, video, audio, PDF, ZIP, gzip, tar, octet-stream - Min threshold 256 bytes to avoid CPU waste on tiny responses - Compatible with future reverse proxy (Content-Encoding passthrough) --- src/main.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/main.rs b/src/main.rs index e23c5ce9..711e489e 100755 --- a/src/main.rs +++ b/src/main.rs @@ -379,6 +379,30 @@ async fn main() -> Result<(), Box> { // Without this Axum caps Multipart bodies at 2 MB. app = app.layer(DefaultBodyLimit::max(10 * 1024 * 1024 * 1024)); + // ── HTTP compression (gzip + Brotli) ───────────────────────────────── + // Negotiates the best encoding via Accept-Encoding. Skips responses + // that are already compressed or wouldn't benefit (images, video, etc.). + // Compatible with a future reverse proxy — if the proxy sees + // `Content-Encoding` it will pass the response through untouched. + { + use tower_http::compression::CompressionLayer; + use tower_http::compression::predicate::{NotForContentType, Predicate, SizeAbove}; + + let predicate = SizeAbove::new(256) + .and(NotForContentType::GRPC) + .and(NotForContentType::IMAGES) + .and(NotForContentType::SSE) + .and(NotForContentType::const_new("application/octet-stream")) + .and(NotForContentType::const_new("application/zip")) + .and(NotForContentType::const_new("application/gzip")) + .and(NotForContentType::const_new("application/x-tar")) + .and(NotForContentType::const_new("application/pdf")) + .and(NotForContentType::const_new("video/")) + .and(NotForContentType::const_new("audio/")); + + app = app.layer(CompressionLayer::new().compress_when(predicate)); + } + // ── Security headers ───────────────────────────────────────────────── // Applied globally so every response (API, static, DAV) carries them. use axum::http::HeaderValue;