Documentation
¶
Index ¶
- Variables
- type CacheKey
- type CacheStatusMode
- type Option
- func WithAutoInvalidateMutatingMethods() Option
- func WithBackgroundFetchTimeout(d time.Duration) Option
- func WithCacheKey(k CacheKey) Option
- func WithCacheStatus(mode CacheStatusMode) Option
- func WithESI(opts ...esi.Option) Option
- func WithLogger(l *slog.Logger) Option
- func WithMetrics(reg prometheus.Registerer) Option
- func WithRespectClientCacheControl() Option
- func WithServerTiming() Option
- func WithServerTimingCookie(name, value string) Option
- func WithStorageTimeout(d time.Duration) Option
- func WithTagHeader(name string) Option
- func WithoutConvertHeadToGet() Option
- type PurgeOption
- type Titip
- func (t *Titip) Close(ctx context.Context) error
- func (t *Titip) Purge(ctx context.Context, target string, opts ...PurgeOption) (int64, error)
- func (t *Titip) PurgeAll(ctx context.Context) (int64, error)
- func (t *Titip) PurgePrefix(ctx context.Context, prefix string, opts ...PurgeOption) (int64, error)
- func (t *Titip) PurgeTag(ctx context.Context, tag string, opts ...PurgeOption) (int64, error)
- func (t *Titip) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.Handler)
Constants ¶
This section is empty.
Variables ¶
var ( // ErrInvalidOption is returned when an invalid configuration option is provided to New. ErrInvalidOption = errors.New("titip: invalid option") )
var ( // ErrStorageRequired is returned by New when the mandatory storage parameter is nil. ErrStorageRequired = errors.New("titip: storage is required") )
Functions ¶
This section is empty.
Types ¶
type CacheKey ¶ added in v0.2.0
type CacheKey struct {
// IncludeProtocol includes the request scheme ("http" or "https") in the cache key.
// When true, HTTP and HTTPS requests reference distinct cache entries.
IncludeProtocol bool
// ExcludeHost excludes the HTTP Host / domain from the cache key.
// When true, Host is omitted so multiple domains serving identical content share cache entries.
ExcludeHost bool
// ExcludeQuery removes all query parameters from the cache key.
// When true, the query component is stripped so requests with different query strings share cache.
ExcludeQuery bool
// PreserveQueryOrder preserves the original query parameter ordering from the request URL.
// When true, query parameter order is preserved as received from the client instead of sorting alphabetically.
PreserveQueryOrder bool
// IncludedQueryParams specifies an allowlist of query parameter names to include in the cache key.
// If set, only these specific parameters are included in the cache key.
IncludedQueryParams []string
// ExcludedQueryParams specifies a denylist of query parameter names to exclude from the cache key.
// If set, all query parameters except these are included in the cache key.
ExcludedQueryParams []string
// ExcludeMarketingQueryParams filters out standard advertising and tracking query parameters
// including all utm_* prefix parameters (e.g. utm_source, utm_campaign, utm_id, utm_content)
// and common advertising click IDs (gclid, fbclid, ttclid, msclkid, etc.).
// When true, marketing tracking parameters are stripped from the cache key.
ExcludeMarketingQueryParams bool
// IncludedHeaderNames specifies request header names whose values are appended to the primary cache key.
//
// Note: Do NOT include headers that the origin already manages via the HTTP "Vary" header
// (e.g. "Accept-Encoding"), as Titip handles origin Vary negotiation automatically.
//
// Warning: NEVER include authentication tokens or credentials (e.g. "Authorization").
// Specifying headers with high cardinality or wide ranges of values dramatically lowers the
// cache hit rate and causes higher eviction churn.
//
// Best used for low-cardinality headers or A/B experiment buckets (e.g. "X-Region", "X-Experiment-Bucket").
IncludedHeaderNames []string
// IncludedCookieNames specifies cookie names whose values are appended to the cache key.
//
// Warning: NEVER include session identifiers, auth cookies, or credentials.
// Including unique per-user cookies effectively creates per-user caches, destroying hit rates.
//
// Best used for low-cardinality user preferences or A/B testing groups (e.g. "ab_group", "currency", "theme", "locale").
IncludedCookieNames []string
// CaseInsensitivePath normalizes the URL path to lowercase in the primary cache key.
// When true, requests with different path casing (e.g. /Products/Shoes vs /products/shoes) share the same cache entry.
CaseInsensitivePath bool
// IncludedQueryParamValues specifies an allowlist of specific parameter values.
// A parameter key in this map is only included in the cache key if its value matches one of the specified allowed values.
// Any value not in the list is omitted from the cache key.
IncludedQueryParamValues map[string][]string
}
CacheKey defines the rules for assembling zero-hash canonical cache keys.
Every cached request automatically receives a cache key. A zero-value CacheKey{} or omitting WithCacheKey applies the standard RFC-compliant default: host included, protocol excluded, case-sensitive path, all query parameters retained, and sorted alphabetically.
type CacheStatusMode ¶
type CacheStatusMode int
CacheStatusMode specifies the format of the emitted Cache-Status header.
const ( // CacheStatusSimpleToken outputs single-token status header (e.g. HIT, MISS, EXPIRED, REVALIDATED, UPDATING, STALE, BYPASS, DYNAMIC) by default. CacheStatusSimpleToken CacheStatusMode = iota // CacheStatusRFC9211 outputs structured RFC-9211 Cache-Status header (e.g. Cache-Status: titip; hit; ttl=240). CacheStatusRFC9211 // CacheStatusNone disables cache status header generation. CacheStatusNone )
type Option ¶
type Option func(*config) error
Option configures Titip middleware options.
func WithAutoInvalidateMutatingMethods ¶
func WithAutoInvalidateMutatingMethods() Option
WithAutoInvalidateMutatingMethods enables automatic invalidation of cached GET entries when successful mutating requests (POST, PUT, DELETE, PATCH) are received for the URI, matching the mandatory invalidation behavior defined in RFC 9111 Section 4.4. By default, this is disabled so applications can rely on explicit tag-based (Cache-Tag) or URL invalidation.
func WithBackgroundFetchTimeout ¶ added in v0.2.0
WithBackgroundFetchTimeout configures the maximum timeout for asynchronous background revalidation (stale-while-revalidate) origin fetches (defaults to 125s). Set to 0 to disable background timeout enforcement.
func WithCacheKey ¶ added in v0.2.0
WithCacheKey customizes the rules for assembling canonical cache keys (such as query parameter filtering, marketing tag removal, and header/cookie dimensions).
A cache key is always automatically generated for every request. If WithCacheKey is omitted, Titip applies standard default key generation (protocol-agnostic, host-aware, case-sensitive path, all query parameters retained, and sorted alphabetically).
func WithCacheStatus ¶ added in v0.3.0
func WithCacheStatus(mode CacheStatusMode) Option
WithCacheStatus configures the Cache-Status header emission mode.
func WithESI ¶
WithESI enables ESI processing with the provided ESI options. If no options are provided, ESI is enabled with safe production defaults.
func WithLogger ¶
WithLogger configures the structured slog.Logger.
func WithMetrics ¶
func WithMetrics(reg prometheus.Registerer) Option
WithMetrics configures the Prometheus metrics registerer.
func WithRespectClientCacheControl ¶
func WithRespectClientCacheControl() Option
WithRespectClientCacheControl enables respecting client request Cache-Control directives (e.g. no-cache, no-store). By default, client cache directives are ignored to protect origin servers.
func WithServerTiming ¶ added in v0.3.0
func WithServerTiming() Option
WithServerTiming enables Server-Timing header diagnostics for TTFB tracing in browser DevTools.
func WithServerTimingCookie ¶ added in v0.3.0
WithServerTimingCookie enables Server-Timing header generation gated by an exact cookie name and value match.
func WithStorageTimeout ¶
WithStorageTimeout configures maximum timeout for storage operations (defaults to 5s).
func WithTagHeader ¶ added in v0.3.0
WithTagHeader configures the response header inspected for cache tags (defaults to "Cache-Tag").
func WithoutConvertHeadToGet ¶ added in v0.3.0
func WithoutConvertHeadToGet() Option
WithoutConvertHeadToGet disables converting origin HEAD cache misses and revalidations to GET. By default, HEAD misses are converted to GET to prime the cache with body bytes. When disabled, HEAD misses query the origin as HEAD and are not saved to cache.
type PurgeOption ¶
type PurgeOption func(*purgeConfig)
PurgeOption configures Purge, PurgeTag, or PurgeAll operations.
func WithSoftPurge ¶
func WithSoftPurge() PurgeOption
WithSoftPurge marks entries as stale rather than evicting immediately (safe thundering-herd mode). The stale copy is preserved for stale-if-error fallback if the origin subsequently fails.
type Titip ¶
type Titip struct {
// contains filtered or unexported fields
}
Titip represents the HTTP caching middleware instance.
func New ¶
New creates a new Titip caching middleware instance. The store parameter is mandatory. If store is nil, ErrStorageRequired is returned.
func (*Titip) Close ¶
Close cleanly shuts down the middleware, awaiting background SWR revalidations.
func (*Titip) Purge ¶
Purge invalidates cache entries matching the specified path or URL (and its query variations).
The target supports the following formats:
- "/api/products" — purges the path and ALL query string variations
- "https://example.com/api/products" — host-scoped path purge (include domain in target to scope by host)
- "https://example.com/api?id=42" — exact query variant (O(1) exact delete)
- "/api/products?id=42" — exact query variant (exact delete if ExcludeHost=true, or across all hosts)
- "/" — purges the homepage only
Note: Purge treats any asterisks in the path literally (not as a wildcard). To purge a path hierarchy or directory prefix, use PurgePrefix().
By default, purge is a hard-delete (immediate physical eviction). Use WithSoftPurge() to mark entries as stale instead for safe thundering-herd protection.
Returns the total number of logical cache entries invalidated.
func (*Titip) PurgePrefix ¶ added in v0.3.0
PurgePrefix invalidates cache entries matching the specified path or URL prefix (Cloudflare-style).
Behavior:
- "/assets/" (with trailing slash) — directory prefix: purges all child paths under /assets/ (does not touch /assets-v2)
- "/assets" (without trailing slash) — raw string prefix: purges /assets, /assets/*, AND /assets-v2
- "/" — purges the entire cache namespace (supports WithSoftPurge())
- "https://example.com/assets/" — host-scoped prefix purge
By default, purge is a hard-delete (immediate physical eviction). Use WithSoftPurge() to mark entries as stale instead for safe thundering-herd protection.
Returns the total number of logical cache entries invalidated.