Skip to main content

Overview

The responsesize middleware tracks response sizes for monitoring, logging, and metrics collection. Use it when you need:
  • Monitor response sizes
  • Collect bandwidth metrics
  • Detect response size anomalies

Installation

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

Quick Start

app := mizu.New()

app.Use(responsesize.New())

Configuration

Options

OptionTypeDefaultDescription
Handlerfunc(*mizu.Ctx, int64)nilSize callback

Examples

Track in Context

app.Use(responsesize.New())

With Callback

app.Use(responsesize.WithHandler(func(c *mizu.Ctx, size int64) {
    metrics.RecordResponseSize(c.Request().URL.Path, size)
}))

Log Large Responses

app.Use(responsesize.WithHandler(func(c *mizu.Ctx, size int64) {
    if size > 1024*1024 { // > 1MB
        log.Printf("Large response: %s %d bytes", c.Request().URL.Path, size)
    }
}))

API Reference

Functions

// New creates response size middleware
func New() mizu.Middleware

// WithHandler creates with callback
func WithHandler(handler func(*mizu.Ctx, int64)) mizu.Middleware

// Get returns response size from context
func Get(c *mizu.Ctx) int64

Technical Details

Implementation Architecture

The middleware uses a wrapping pattern to intercept and track response writes:
  1. Context Storage: Response size information is stored in the request context using a custom contextKey type for type-safe retrieval.
  2. Writer Wrapping: The middleware wraps the original http.ResponseWriter with a trackingWriter that intercepts all Write() calls.
  3. Atomic Tracking: Uses sync/atomic operations to safely track bytes written, ensuring thread-safe counting even with concurrent writes.
  4. Callback Mechanism: After the response is fully written, an optional callback (OnSize) is invoked with the total byte count.

Key Components

  • Info struct: Holds the bytesWritten counter with an atomic accessor method BytesWritten().
  • trackingWriter: A wrapper around http.ResponseWriter that increments the byte counter on each write.
  • contextKey: An empty struct used as a unique key for storing size info in the context.

Flow

  1. Create Info instance and store in context
  2. Wrap response writer with trackingWriter
  3. Execute next handler in chain
  4. Invoke OnSize callback with final byte count
  5. Restore original writer

Best Practices

  • Track alongside request sizes
  • Set alerts for unusually large responses
  • Use for bandwidth billing
  • Monitor compression effectiveness

Testing

The middleware includes comprehensive test coverage:
Test CaseDescriptionExpected Behavior
TestNewBasic middleware creationMiddleware executes without errors and returns 200 OK
TestWithOptions_CallbackOnSize callback functionalityCallback receives correct byte count (5 bytes for “12345”)
TestBytesWrittenBytesWritten helper functionReturns accurate byte count matching response body length
TestGetInfo retrieval from contextGet() returns valid Info instance from context
TestWithCallbackWithCallback convenience functionCallback is invoked with correct size (3 bytes for “abc”)
TestEmptyResponseEmpty response handlingReports 0 bytes for 204 No Content responses
TestMultipleWritesMultiple Write() callsAccumulates bytes across multiple writes (“firstsecondthird” = 16 bytes)