Skip to main content

Overview

The compress middleware automatically compresses HTTP responses using gzip or deflate encoding when the client supports it. This reduces bandwidth usage and improves load times for text-based content. Use it when you need:
  • Reduced bandwidth for API responses
  • Faster page loads for web applications
  • Compression for JSON, HTML, CSS, and JavaScript

Installation

import "github.com/go-mizu/mizu/middlewares/compress"

Quick Start

app := mizu.New()

// Enable gzip compression
app.Use(compress.Gzip())

// Or enable deflate
app.Use(compress.Deflate())

Configuration

Options

OptionTypeDefaultDescription
Levelint6Compression level (1-9)
MinSizeint1024Minimum response size to compress
ContentTypes[]stringText typesContent types to compress

Examples

Gzip Compression

app.Use(compress.Gzip())

Custom Compression Level

// Best compression (slower)
app.Use(compress.GzipLevel(9))

// Fastest compression
app.Use(compress.GzipLevel(1))

With Options

app.Use(compress.New(compress.Options{
    MinSize: 1000, // Only compress responses > 1KB
    ContentTypes: []string{
        "text/plain",
        "text/html",
        "text/css",
        "application/json",
        "application/javascript",
    },
}))

Auto-Select Encoding

// Automatically selects gzip or deflate based on Accept-Encoding
app.Use(compress.New(compress.Options{
    MinSize: 512,
}))

API Reference

Functions

// Gzip creates gzip compression middleware
func Gzip() mizu.Middleware

// GzipLevel creates gzip middleware with specific level
func GzipLevel(level int) mizu.Middleware

// Deflate creates deflate compression middleware
func Deflate() mizu.Middleware

// New creates compression middleware with options
func New(opts Options) mizu.Middleware

Compression Levels

LevelDescription
1Best speed, least compression
6Default balance
9Best compression, slowest

Behavior

  • Automatically sets Content-Encoding header
  • Adds Vary: Accept-Encoding header
  • Skips compression if client doesn’t support it
  • Skips already-encoded responses
  • Skips responses smaller than MinSize

Technical Details

Implementation Overview

The compress middleware uses a buffering strategy to determine whether compression should be applied:
  1. Buffering Phase: Responses are buffered until they reach the MinSize threshold
  2. Decision Point: Once the threshold is reached, the middleware checks:
    • If the client supports the requested encoding (via Accept-Encoding header)
    • If the content type is compressible (matches ContentTypes list)
    • If the response is not already encoded (no existing Content-Encoding header)
  3. Compression Phase: If all checks pass, the appropriate compression writer is applied

Writer Pooling

The middleware uses sync.Pool to efficiently reuse compression writers:
  • Gzip Pool: Maintains a pool of gzip.Writer instances
  • Deflate Pool: Maintains a pool of flate.Writer instances
  • Writers are reset and returned to the pool after each request
  • This reduces garbage collection pressure and improves performance

Custom Response Writer

The compressWriter wraps the standard http.ResponseWriter and provides:
  • Buffering: Accumulates response data until compression decision is made
  • Lazy Header Writing: Delays header writing until compression status is determined
  • Automatic Cleanup: Ensures compression writers are properly closed and returned to pool
  • Flush Support: Implements http.Flusher for streaming responses

Encoding Selection

When using New() with auto-selection:
  1. Checks for gzip in Accept-Encoding header first (preferred)
  2. Falls back to deflate if gzip is not supported
  3. Uses no compression if neither is supported
When using specific functions (Gzip(), Deflate()):
  • Only applies compression if the client explicitly supports the selected encoding

Default Content Types

The following content types are compressed by default:
  • text/html, text/css, text/plain, text/javascript, text/xml
  • application/json, application/javascript, application/xml
  • application/xhtml+xml, application/rss+xml, application/atom+xml
  • image/svg+xml

Best Practices

  • Use level 6 for most applications (good balance)
  • Set appropriate MinSize to avoid compressing tiny responses
  • Only compress text-based content types
  • Place before other response-modifying middleware

Testing

The compress middleware includes comprehensive test coverage for various scenarios:
Test CaseDescriptionExpected Behavior
TestGzip/compresses responseTests basic gzip compression with large responseResponse is compressed with gzip, Content-Encoding header set to “gzip”, body can be decompressed correctly
TestGzip/skips without accept-encodingTests behavior when Accept-Encoding header is missingResponse is not compressed, no Content-Encoding header set
TestGzip/sets vary headerTests Vary header is properly setVary header contains “Accept-Encoding”
TestGzipLevelTests gzip compression with specific level (level 9)Response is compressed with specified compression level, Content-Encoding set to “gzip”
TestDeflateTests deflate compression algorithmResponse is compressed with deflate, Content-Encoding header set to “deflate”
TestNew_SmallResponseTests MinSize threshold with response smaller than limitSmall responses (< MinSize) are not compressed
TestNew_NonCompressibleTypeTests content type filteringNon-text content types (e.g., application/octet-stream) are not compressed
TestNew_AlreadyEncodedTests handling of pre-encoded responsesExisting Content-Encoding header is preserved, no double compression
TestNew_AutoSelectEncodingTests automatic encoding selection based on Accept-EncodingMiddleware selects gzip or deflate based on client preference, prefers gzip when both available
  • cache - HTTP caching
  • etag - ETag generation
  • vary - Vary header management