RFC 9213 Targeted Cache-Control
RFC 9213 Targeted HTTP Cache-Control directives. Operators address specific layers in the caching chain by setting parallel headers that share the Cache-Control directive grammar but apply only to caches matching the target. The well-known shapes:
Cache-Control: max-age=60 (user-agent cache) CDN-Cache-Control: max-age=3600 (every CDN class cache) Cloudflare-CDN-Cache-Control: max-age=86400 (CDN-specific override) Vercel-CDN-Cache-Control: max-age=86400 (CDN-specific override) Surrogate-Control: max-age=3600 (W3C Edge Architecture)
The same response can carry multiple targeted variants — a CDN that recognizes its operator-specific header uses that one; CDNs without a match fall back to CDN-Cache-Control; user agents apply only the plain Cache-Control. The framework treats every variant as the same RFC 9111 §5.2.2 directive grammar.
build({...}) emits a directive string for any of the targeted headers; the operator chooses which header name to set. parse() round-trips: decode an inbound directive list into a normalized object with numeric maxAge / staleWhileRevalidate, boolean flags (public / private / noStore / noCache / mustRevalidate / immutable), and the raw directives map for unknown / extension keys.
TARGETED_HEADERS lists the well-known header names the operator may set; an explicit allowlist instead of guessing prevents operators from emitting a malformed CDN-Cache-Control-X-Custom header that no cache will look at.
b.cdnCacheControl.build(opts) #
{
maxAge: number, // max-age=N (user-agent + shared)
sMaxAge: number, // s-maxage=N (shared caches only)
staleWhileRevalidate: number, // RFC 5861 §3
staleIfError: number, // RFC 5861 §4
minFresh: number, // request directive
maxStale: number, // request directive
public: boolean,
private: boolean,
noStore: boolean,
noCache: boolean,
mustRevalidate: boolean,
proxyRevalidate: boolean,
mustUnderstand: boolean, // RFC 8246
noTransform: boolean,
immutable: boolean, // RFC 8246
extensions: object, // raw key→value/true map for non-standard directives
}
Build a Cache-Control-style directive list string for any RFC 9213 targeted header. opts accepts the standard RFC 9111 §5.2.2 directives in camelCase (maxAge, sMaxAge, staleWhileRevalidate, staleIfError, mustRevalidate, etc.) — kebab-case keys (max-age, s-maxage, ...) also pass through unchanged for operators porting from existing header-building code.
Numeric directives accept non-negative finite integers; the primitive refuses negative / non-integer / Infinity / NaN inputs (the directive grammar requires delta-seconds). Boolean directives only emit when explicitly true; false / undefined omit the token.
Returns the directive list string ready to be assigned to any header in TARGETED_HEADERS. Caller is responsible for choosing which header name to set.
res.setHeader("CDN-Cache-Control", b.cdnCacheControl.build({
public: true,
sMaxAge: 3600,
staleWhileRevalidate: 60,
staleIfError: 86400,
}));
// → "public, s-maxage=3600, stale-while-revalidate=60, stale-if-error=86400"
res.setHeader("Cache-Control", b.cdnCacheControl.build({
private: true, maxAge: 0, noStore: true,
}));
// → "private, max-age=0, no-store"
b.cdnCacheControl.parse(headerValue) #
Parse a Cache-Control-style directive list (from any RFC 9213 targeted header) into a normalized object. Returns null for absent / empty / non-string input — operator code branches on null vs the populated shape.
Numeric directives are surfaced as camelCase number fields (maxAge, sMaxAge, staleWhileRevalidate, staleIfError, minFresh, maxStale); boolean directives as camelCase boolean fields. Unknown directives land in directives (a name → value map where boolean directives map to true and value-bearing directives map to the raw string).
Defensive parser: tolerates trailing semicolons, repeated whitespace, and unquoted-quoted-string values; refuses control characters in the header value (CR/LF/NUL/DEL header-injection shape) by throwing cdn-cache-control/bad-header-value. ASCII HT remains permitted (structural folding whitespace).
b.cdnCacheControl.parse("public, s-maxage=3600, stale-while-revalidate=60");
// → { public: true, sMaxAge: 3600, staleWhileRevalidate: 60, directives: {} }
b.cdnCacheControl.parse("private, no-store, x-foo=bar");
// → { private: true, noStore: true, directives: { "x-foo": "bar" } }
b.cdnCacheControl.isTargetedHeader(headerName) #
Returns true when headerName matches one of the well-known RFC 9213 targeted header names (case-insensitive). Operators auditing an inbound response's cache headers walk the response headers and call this to identify which directive lists were intended for which cache class.
b.cdnCacheControl.isTargetedHeader("CDN-Cache-Control"); // → true
b.cdnCacheControl.isTargetedHeader("cloudflare-cdn-cache-control"); // → true
b.cdnCacheControl.isTargetedHeader("Cache"); // → false
Last updated 2026-08-08T16:39:49.652Z by seeder.