compression

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 19, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

README

Compression

Go Reference Go Version License

Compress HTTP responses automatically. Uses gzip, deflate, or brotli based on what the client supports. Reduces bandwidth and often speeds up responses for text and JSON.

Full docs: Middleware Guide and Middleware Reference.

Features

  • Gzip, deflate, and brotli support (picks the best the client accepts)
  • Compresses text, JSON, XML, and similar; skips images and other binary types by default
  • Configurable compression level and minimum size
  • Skip compression for specific paths (e.g. /metrics)
  • No change needed in your handlers; compression happens in the middleware

Installation

go get rivaas.dev/middleware/compression

Requires Go 1.25 or later.

Quick Start

package main

import (
    "net/http"
    "rivaas.dev/router"
    "rivaas.dev/middleware/compression"
)

func main() {
    r := router.New()
    r.Use(compression.New())

    r.GET("/", func(c *router.Context) {
        c.JSON(http.StatusOK, map[string]string{"message": "This response is compressed"})
    })

    http.ListenAndServe(":8080", r)
}

Configuration

Option What it does
WithGzipLevel Gzip level 0–9 (higher = smaller but slower; default is standard)
WithBrotliLevel Brotli level 0–11 (default 4 for dynamic content)
WithBrotliDisabled Use only gzip and deflate
WithMinSize Do not compress responses smaller than this (bytes)
WithContentTypes Only compress these content types (default: text/*, application/json, etc.)
WithExcludePaths Paths that are never compressed

Example with custom settings:

r.Use(compression.New(
    compression.WithGzipLevel(6),
    compression.WithMinSize(1024),        // Skip if response < 1KB
    compression.WithExcludePaths("/metrics"),
))

Examples

A runnable example is in the example/ directory:

cd example
go run main.go

Then send a request with Accept-Encoding: gzip and check the response.

Learn More

License

Apache License 2.0 – see LICENSE for details.

Documentation

Overview

Package compression provides middleware for HTTP response compression.

This middleware automatically compresses HTTP responses using gzip, deflate, or brotli compression algorithms based on client Accept-Encoding headers. It reduces bandwidth usage and improves response times for text-based content.

Basic Usage

import "rivaas.dev/middleware/compression"

r := router.MustNew()
r.Use(compression.New())

Supported Algorithms

The middleware supports multiple compression algorithms:

  • gzip: Standard gzip compression (widely supported)
  • deflate: Deflate compression (legacy support)
  • brotli: Brotli compression (better compression ratio, modern browsers)

The middleware automatically selects the best algorithm based on client Accept-Encoding headers and configured preferences.

Configuration Options

  • Level: Compression level (1-9, higher = better compression but slower)
  • MinSize: Minimum response size to compress (default: 1KB)
  • ContentTypes: Content types to compress (default: text/*, application/json, etc.)
  • ExcludePaths: Paths to exclude from compression (e.g., /metrics)
  • Logger: Optional logger for compression events

Content Type Filtering

By default, the middleware compresses text-based content types:

  • text/*
  • application/json
  • application/javascript
  • application/xml
  • application/xhtml+xml

Binary content types (images, videos, etc.) are excluded by default.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func New

func New(opts ...Option) router.HandlerFunc

New returns a middleware that compresses HTTP responses using gzip and/or Brotli. It automatically detects client support and selects the best encoding based on Accept-Encoding header with q-value negotiation.

Features:

  • Automatic gzip and Brotli compression with quality-value negotiation
  • Configurable compression levels for both algorithms
  • Minimum size threshold with buffering to avoid compressing small responses
  • Path and content-type exclusions
  • Writer pooling for reduced allocations
  • Skips compression for 204, 304, 206, SSE, and gRPC
  • Sets Vary: Accept-Encoding header
  • Respects existing Content-Encoding headers (proxying)

Basic usage:

r := router.MustNew()
r.Use(compression.New())

With custom compression levels:

r.Use(compression.New(
    compression.WithGzipLevel(gzip.BestCompression),
    compression.WithBrotliLevel(5),
))

Disable Brotli (gzip only):

r.Use(compression.New(
    compression.WithBrotliDisabled(),
))

Exclude certain paths:

r.Use(compression.New(
    compression.WithExcludePaths("/metrics", "/stream"),
))

Exclude already compressed formats:

r.Use(compression.New(
    compression.WithExcludeExtensions(".jpg", ".png", ".gif", ".zip"),
    compression.WithExcludeContentTypes("image/jpeg", "image/png"),
))

Types

type Option

type Option func(*config)

Option defines functional options for compression middleware configuration.

func WithBrotliDisabled

func WithBrotliDisabled() Option

WithBrotliDisabled disables Brotli compression (gzip only).

Example:

compression.New(compression.WithBrotliDisabled())

func WithBrotliLevel

func WithBrotliLevel(level int) Option

WithBrotliLevel sets the Brotli compression level. Valid values: 0 (no compression) to 11 (best compression). For dynamic content (JSON/text), use 4-5. Higher levels are CPU-expensive. Default: 4 (conservative for dynamic content)

Example:

compression.New(compression.WithBrotliLevel(5))

func WithExcludeContentTypes

func WithExcludeContentTypes(contentTypes ...string) Option

WithExcludeContentTypes sets content types that should not be compressed. Already compressed content types don't benefit from compression.

Example:

compression.New(compression.WithExcludeContentTypes("image/jpeg", "image/png", "application/zip"))

func WithExcludeExtensions

func WithExcludeExtensions(extensions ...string) Option

WithExcludeExtensions sets file extensions that should not be compressed. Already compressed formats don't benefit from compression. Default: none (but should typically exclude .jpg, .png, .gif, .zip, etc.)

Example:

compression.New(compression.WithExcludeExtensions(".jpg", ".png", ".gif", ".zip", ".gz"))

func WithExcludePaths

func WithExcludePaths(paths ...string) Option

WithExcludePaths sets paths that should not be compressed. Useful for endpoints that already serve compressed content or streaming responses.

Example:

compression.New(compression.WithExcludePaths("/metrics", "/stream"))

func WithGzipDisabled

func WithGzipDisabled() Option

WithGzipDisabled disables gzip compression (Brotli only).

Example:

compression.New(compression.WithGzipDisabled())

func WithGzipLevel

func WithGzipLevel(level int) Option

WithGzipLevel sets the gzip compression level. Valid values: 0 (no compression) to 9 (best compression). Default: gzip.DefaultCompression (-1, which is typically level 6)

Example:

compression.New(compression.WithGzipLevel(gzip.BestCompression))

func WithLogger

func WithLogger(logger *slog.Logger) Option

WithLogger sets the slog.Logger for error logging. If not provided, errors will be silently ignored.

Uses the standard library's log/slog package for structured logging:

import "log/slog"

logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
compression.New(compression.WithLogger(logger))

Example:

import "log/slog"

logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
r.Use(compression.New(compression.WithLogger(logger)))

func WithMinSize

func WithMinSize(size int) Option

WithMinSize sets the minimum response size to compress (in bytes).

DESIGN DECISION: This feature is intentionally NOT implemented.

Why minSize is not implemented:

  • Requires buffering entire response before compression decision
  • Adds memory overhead (buffer per request)
  • Adds latency (wait for full response before sending)
  • Breaks streaming responses
  • Modern networks handle small compressed payloads efficiently

Alternative approaches (recommended):

  • Use WithExcludePaths for small endpoints
  • Use WithExcludeContentTypes for small data types
  • Let CDN/reverse proxy handle compression (nginx, CloudFlare)

If you truly need minSize, implement at the reverse proxy level where buffering is already happening (nginx, CloudFlare, etc.)

This option exists for API compatibility but is a no-op. Default: 1024 (1KB, not enforced)

Example:

compression.New(compression.WithMinSize(2048)) // No effect (by design)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL