Package rfc9111
Overview
Package rfc9111 builds Cache-Control response directives, as defined by RFC 9111 (HTTP Caching).
It matters for error responses because some error status codes are heuristically cacheable: a cache may store and reuse a 404, 405, 410, 414 or 501 response that has no explicit freshness information (RFC 9110, Section 15.1, and RFC 9111, Section 4.2.2). Send NoStore with an error that mustn't be reused:
rfc9110.NotFound().WithCacheControl(rfc9111.NoStore())A client that caches what it fetches reads a response's directives with ParseCacheControl:
cc := rfc9111.ParseCacheControl(resp.Header.Values("Cache-Control")...)
if maxAge, ok := cc.MaxAge(); ok && !cc.NoStore() && !cc.NoCache() {
// Reuse the response for up to maxAge.
}The package covers the response directives of Section 5.2.2, without the optional field-name lists of no-cache and private, and parses the ones a private cache needs to decide on reuse. It doesn't cover request directives.
The RFC text is in rfc9111.txt in this directory, and the doc comments cite its sections.
Index
Functions
Format source
func Format(dirs ...Directive) stringFormat returns the directives as a Cache-Control field value, such as
"no-store, max-age=0". It leaves out zero Directives. ExampleFormat shows a Cache-Control value that stops caches reusing a 404,
which is heuristically cacheable. Output:Example
package main
import (
"fmt"
"net/http"
"funnyhaha.technology/rfc/rfc9111"
)
func main() {
fmt.Println(rfc9111.Format(rfc9111.NoStore(), rfc9111.MaxAge(0)))
fmt.Println(rfc9111.HeuristicallyCacheable(http.StatusNotFound))
}
no-store, max-age=0
true
HeuristicallyCacheable source
func HeuristicallyCacheable(code int) boolHeuristicallyCacheable reports whether a response with the status code may be stored and reused by a cache when it has no explicit freshness information. These are the codes RFC 9110, Section 15.1, lists: 200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414 and 501.
See RFC 9111, Section 4.2.2.
Types
CacheControl source
type CacheControl struct {
// contains filtered or unexported fields
}CacheControl is the response directives read from a Cache-Control field by ParseCacheControl: the ones that decide whether, and for how long, a private cache may reuse a response.
See RFC 9111, Section 5.2.2.
ParseCacheControl source
func ParseCacheControl(lines ...string) CacheControlParseCacheControl reads the response directives max-age, no-store, no-cache and private from the Cache-Control field lines, and ignores the rest, as Section 5.2.3 requires of unrecognised directives. Directive names are compared case-insensitively, and an argument may be a token or a quoted-string (Section 5.2).
When max-age appears more than once, the first is used (Section 4.2.1). An invalid max-age makes the response stale, a max-age of 0, which Section 4.2.1 allows. A no-cache or private with a list of field names is treated as if it had none, which is the stricter reading.
(CacheControl) MaxAge source
func (cc CacheControl) MaxAge() (time.Duration, bool)MaxAge returns the max-age directive's duration, and whether it was present (Section 5.2.2.1).
(CacheControl) NoCache source
func (cc CacheControl) NoCache() boolNoCache reports whether no-cache was present: a cache mustn't reuse the response without revalidating it (Section 5.2.2.4).
(CacheControl) NoStore source
func (cc CacheControl) NoStore() boolNoStore reports whether no-store was present: a cache mustn't store the response (Section 5.2.2.5).
(CacheControl) Private source
func (cc CacheControl) Private() boolPrivate reports whether private was present: a shared cache mustn't store the response, though a private cache may (Section 5.2.2.7).
Directive source
type Directive struct {
// contains filtered or unexported fields
}Directive is a Cache-Control response directive. Build one with its constructor, such as NoStore or MaxAge. The zero Directive is empty, and Format leaves it out.
See RFC 9111, Section 5.2.2.
MaxAge source
func MaxAge(d time.Duration) DirectiveMaxAge returns max-age: the response is stale once its age exceeds d (Section 5.2.2.1). d is rounded down to whole seconds, a negative d is treated as zero, and d is capped at 2^31 seconds (Section 1.2.2).
MustRevalidate source
func MustRevalidate() DirectiveMustRevalidate returns must-revalidate: a cache mustn't reuse the response once it's stale without revalidating it (Section 5.2.2.2).
MustUnderstand source
func MustUnderstand() DirectiveMustUnderstand returns must-understand: a cache may store the response only if it understands the requirements of its status code (Section 5.2.2.3).
NoCache source
func NoCache() DirectiveNoCache returns no-cache: a cache mustn't reuse the response without revalidating it (Section 5.2.2.4).
NoStore source
func NoStore() DirectiveNoStore returns no-store: a cache mustn't store the response (Section 5.2.2.5).
NoTransform source
func NoTransform() DirectiveNoTransform returns no-transform: an intermediary mustn't transform the content (Section 5.2.2.6).
Private source
func Private() DirectivePrivate returns private: a shared cache mustn't store the response (Section 5.2.2.7).
ProxyRevalidate source
func ProxyRevalidate() DirectiveProxyRevalidate returns proxy-revalidate: must-revalidate, for shared caches only (Section 5.2.2.8).
Public source
func Public() DirectivePublic returns public: a cache may store the response, even if it would otherwise be prohibited (Section 5.2.2.9).
SMaxAge source
func SMaxAge(d time.Duration) DirectiveSMaxAge returns s-maxage: max-age, for shared caches only (Section 5.2.2.10). d is treated as in MaxAge.
(Directive) String source
func (d Directive) String() stringString returns the directive as sent, such as "max-age=60".