@@ -256,6 +256,85 @@ func TestMiddleware_SkipsBelowMinSize(t *testing.T) {
256256 }
257257}
258258
259+ // TestMiddleware_MaxCompressSize verifies SEC-005: bodies exceeding
260+ // MaxCompressSize are served uncompressed, while bodies under the limit
261+ // are still gzipped normally.
262+ func TestMiddleware_MaxCompressSize (t * testing.T ) {
263+ const limit = 2048
264+
265+ makeHandler := func (body string ) fasthttp.RequestHandler {
266+ return func (ctx * fasthttp.RequestCtx ) {
267+ ctx .Response .Header .Set ("Content-Type" , "text/html; charset=utf-8" )
268+ ctx .SetBody ([]byte (body ))
269+ }
270+ }
271+
272+ t .Run ("under limit is compressed" , func (t * testing.T ) {
273+ cfg := & config.CompressionConfig {Enabled : true , MinSize : 10 , Level : 5 , MaxCompressSize : limit }
274+ body := strings .Repeat ("A" , limit - 1 ) // 2047 bytes — just under
275+ handler := compress .Middleware (cfg , makeHandler (body ))
276+ ctx := newTestCtx ("GET" , "/" , map [string ]string {"Accept-Encoding" : "gzip" })
277+ handler (ctx )
278+
279+ if enc := string (ctx .Response .Header .Peek ("Content-Encoding" )); enc != "gzip" {
280+ t .Errorf ("Content-Encoding = %q, want gzip for body under MaxCompressSize" , enc )
281+ }
282+ // Verify decompressed content matches.
283+ gr , err := gzip .NewReader (bytes .NewReader (ctx .Response .Body ()))
284+ if err != nil {
285+ t .Fatalf ("gzip.NewReader: %v" , err )
286+ }
287+ got , err := io .ReadAll (gr )
288+ if err != nil {
289+ t .Fatalf ("io.ReadAll: %v" , err )
290+ }
291+ if string (got ) != body {
292+ t .Error ("decompressed body does not match original" )
293+ }
294+ })
295+
296+ t .Run ("over limit stays uncompressed" , func (t * testing.T ) {
297+ cfg := & config.CompressionConfig {Enabled : true , MinSize : 10 , Level : 5 , MaxCompressSize : limit }
298+ body := strings .Repeat ("B" , limit + 1 ) // 2049 bytes — just over
299+ handler := compress .Middleware (cfg , makeHandler (body ))
300+ ctx := newTestCtx ("GET" , "/" , map [string ]string {"Accept-Encoding" : "gzip" })
301+ handler (ctx )
302+
303+ if enc := string (ctx .Response .Header .Peek ("Content-Encoding" )); enc == "gzip" {
304+ t .Error ("Content-Encoding should not be gzip for body exceeding MaxCompressSize" )
305+ }
306+ if string (ctx .Response .Body ()) != body {
307+ t .Error ("body should be served uncompressed and unmodified" )
308+ }
309+ })
310+
311+ t .Run ("exactly at limit stays uncompressed" , func (t * testing.T ) {
312+ cfg := & config.CompressionConfig {Enabled : true , MinSize : 10 , Level : 5 , MaxCompressSize : limit }
313+ body := strings .Repeat ("C" , limit ) // exactly 2048 bytes — not strictly less
314+ handler := compress .Middleware (cfg , makeHandler (body ))
315+ ctx := newTestCtx ("GET" , "/" , map [string ]string {"Accept-Encoding" : "gzip" })
316+ handler (ctx )
317+
318+ // len(body) > cfg.MaxCompressSize is false when equal, so it IS compressed.
319+ // This tests the boundary condition: equal means "still under the limit".
320+ if enc := string (ctx .Response .Header .Peek ("Content-Encoding" )); enc != "gzip" {
321+ t .Errorf ("Content-Encoding = %q, want gzip when body size equals MaxCompressSize (not strictly over)" , enc )
322+ }
323+ })
324+
325+ t .Run ("zero disables the limit" , func (t * testing.T ) {
326+ cfg := & config.CompressionConfig {Enabled : true , MinSize : 10 , Level : 5 , MaxCompressSize : 0 }
327+ body := strings .Repeat ("D" , 100_000 ) // 100 KB — would exceed any reasonable limit
328+ handler := compress .Middleware (cfg , makeHandler (body ))
329+ ctx := newTestCtx ("GET" , "/" , map [string ]string {"Accept-Encoding" : "gzip" })
330+ handler (ctx )
331+
332+ if enc := string (ctx .Response .Header .Peek ("Content-Encoding" )); enc != "gzip" {
333+ t .Errorf ("Content-Encoding = %q, want gzip when MaxCompressSize=0 (disabled)" , enc )
334+ }
335+ })
336+ }
337+
259338// TestMiddleware_SkipsAlreadyEncoded ensures pre-encoded responses are passed through.
260339func TestMiddleware_SkipsAlreadyEncoded (t * testing.T ) {
261340 cfg := & config.CompressionConfig {Enabled : true , MinSize : 1 , Level : 5 }
0 commit comments