Documentation
¶
Overview ¶
Package etag provides ETag generation and validation middleware.
ETags enable HTTP conditional requests, allowing clients to cache responses and avoid re-downloading unchanged content.
Usage ¶
import "github.com/alexferl/zerohttp/middleware/etag"
// Use defaults (MD5-based ETags)
app.Use(etag.New())
// Custom configuration
app.Use(etag.New(etag.Config{
Weak: true, // Use weak ETags (prefixed with W/)
}))
The middleware automatically handles If-None-Match and If-Match headers, returning 304 Not Modified when content hasn't changed.
Index ¶
- Variables
- func GenerateFromFile(modTime int64, size int64, weak bool) string
- func GenerateFromFileInfo(info interface{ ... }, weak bool) string
- func Matches(ifNoneMatch, etag string) bool
- func New(cfg ...Config) func(http.Handler) http.Handler
- func Parse(etag string) (string, bool)
- func ServeContentWithETag(w http.ResponseWriter, r *http.Request, modTime int64, content io.ReadSeeker)
- type Algorithm
- type Config
Constants ¶
This section is empty.
Variables ¶
var DefaultConfig = Config{ Algorithm: FNV, Weak: config.Bool(false), MaxBufferSize: 1024 * 1024, SkipStatusCodes: map[int]struct{}{ http.StatusNoContent: {}, http.StatusPartialContent: {}, http.StatusMovedPermanently: {}, http.StatusFound: {}, http.StatusNotModified: {}, http.StatusTemporaryRedirect: {}, http.StatusPermanentRedirect: {}, http.StatusBadRequest: {}, http.StatusUnauthorized: {}, http.StatusForbidden: {}, http.StatusNotFound: {}, http.StatusMethodNotAllowed: {}, http.StatusInternalServerError: {}, http.StatusBadGateway: {}, http.StatusServiceUnavailable: {}, }, SkipContentTypes: map[string]struct{}{ httpx.MIMETextEventStream: {}, }, ExcludedPaths: []string{}, IncludedPaths: []string{}, ExcludedFunc: nil, }
DefaultConfig contains the default values for ETag configuration
Functions ¶
func GenerateFromFile ¶
GenerateFromFile generates an etag for a file based on its modification time and size. This is much more efficient than hashing the file content, especially for large files. The format is: W/"mtime-size" (weak etag) or "mtime-size" (strong etag) Example: W/"1709999999-1024"
Usage:
file, _ := os.Open("largefile.zip")
stat, _ := file.Stat()
etag := etag.GenerateFromFile(stat.ModTime().Unix(), stat.Size(), true) // weak ETag
w.Header().Set(httpx.HeaderETag, etag)
func GenerateFromFileInfo ¶
GenerateFromFileInfo generates an etag from fs.FileInfo or os.FileInfo. This helper handles both interface types properly.
Usage:
file, _ := os.Open("largefile.zip")
stat, _ := file.Stat()
etag := etag.GenerateFromFileInfo(stat, true)
w.Header().Set(httpx.HeaderETag, etag)
func Parse ¶
Parse extracts the hash value from an etag, handling weak ETags Returns the hash value and a boolean indicating if it was a weak etag Example: Parse(`W/"abc123"`) returns ("abc123", true) Example: Parse(`"abc123"`) returns ("abc123", false)
func ServeContentWithETag ¶
func ServeContentWithETag(w http.ResponseWriter, r *http.Request, modTime int64, content io.ReadSeeker)
ServeContentWithETag serves content with automatic etag support. It handles If-None-Match and If-Range headers properly. Similar to http.ServeContent but with our etag generation logic.
Types ¶
type Config ¶
type Config struct {
// Algorithm selects the hashing function.
// Default: FNV
Algorithm Algorithm
// Weak determines if ETags should be prefixed with "W/".
// Use a pointer to distinguish between "not set" and "explicitly set to false".
// Default: false
Weak *bool
// MaxBufferSize is the maximum response body size to buffer for ETag generation.
// Default: 1MB
MaxBufferSize int64
// SkipStatusCodes contains status codes that should not have ETags generated.
// Default: error status codes (4xx, 5xx, redirects)
SkipStatusCodes map[int]struct{}
// SkipContentTypes contains content types that should not have ETags generated.
// Default: [text/event-stream]
SkipContentTypes map[string]struct{}
// ExcludedPaths contains paths to skip ETag generation.
// Supports exact matches, prefixes (ending with /), and wildcards (ending with *).
// Cannot be used with IncludedPaths - setting both will panic.
// Default: []
ExcludedPaths []string
// IncludedPaths contains paths where ETag generation is explicitly applied.
// If set, ETag will only be generated for paths matching these patterns.
// Supports exact matches, prefixes (ending with /), and wildcards (ending with *).
// If empty, ETag applies to all paths (subject to ExcludedPaths).
// Cannot be used with ExcludedPaths - setting both will panic.
// Default: []
IncludedPaths []string
// ExcludedFunc is a custom function to determine if ETag generation should be skipped for a request
ExcludedFunc func(r *http.Request) bool
}
Config allows customization of ETag middleware behavior