]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
cache/httpcache: Add respectCacheControlNoStoreInResponse and respectCacheControlNoSt...
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 29 Sep 2025 11:05:24 +0000 (13:05 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 29 Sep 2025 15:06:50 +0000 (17:06 +0200)
This cache is used by `resources.GetRemote`.

Default values are:

* respectCacheControlNoStoreInResponse: false
* respectCacheControlNoStoreInRequest: true

This is a slightly breaking change, but the current behaviour is confusing, as:

* Many servers set the `no-store` header without much consideration, see https://developer.chrome.com/docs/web-platform/bfcache-ccns for more context
* We almost always want to cache the `resources.GetRemote` to disk.

Fixes #13990

cache/httpcache/httpcache.go
go.mod
go.sum
resources/resource_factories/create/create.go

index bd6d4bf7db47edb3e80310d9073b29f2eac87253..010b12e57a4a2de7367e25ad2e89644a686868c6 100644 (file)
@@ -25,6 +25,8 @@ import (
 
 // DefaultConfig holds the default configuration for the HTTP cache.
 var DefaultConfig = Config{
+       RespectCacheControlNoStoreInRequest:  true,
+       RespectCacheControlNoStoreInResponse: false,
        Cache: Cache{
                For: GlobMatcher{
                        Excludes: []string{"**"},
@@ -42,7 +44,13 @@ var DefaultConfig = Config{
 
 // Config holds the configuration for the HTTP cache.
 type Config struct {
-       // Configures the HTTP cache behavior (RFC 9111).
+       // When enabled and there's a Cache-Control: no-store directive in the request, response will never be stored in disk cache.
+       RespectCacheControlNoStoreInRequest bool
+
+       // When enabled and there's a Cache-Control: no-store directive in the response, response will never be stored in disk cache.
+       RespectCacheControlNoStoreInResponse bool
+
+       // Enables HTTP cache behavior (RFC 9111) for these resources.
        // When this is not enabled for a resource, Hugo will go straight to the file cache.
        Cache Cache
 
@@ -57,7 +65,9 @@ type Cache struct {
 }
 
 func (c *Config) Compile() (ConfigCompiled, error) {
-       var cc ConfigCompiled
+       cc := ConfigCompiled{
+               Base: *c,
+       }
 
        p, err := c.Cache.For.CompilePredicate()
        if err != nil {
@@ -127,6 +137,7 @@ func (gm GlobMatcher) IsZero() bool {
 }
 
 type ConfigCompiled struct {
+       Base        Config
        For         predicate.P[string]
        PollConfigs []PollConfigCompiled
 }
diff --git a/go.mod b/go.mod
index da209774aba174ea2e92174449c1e775868a42be..9fabd69f65ec4b6ee1bc47f161a9e3a4d22c853e 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -37,7 +37,7 @@ require (
        github.com/gobwas/glob v0.2.3
        github.com/gohugoio/go-i18n/v2 v2.1.3-0.20230805085216-e63c13218d0e
        github.com/gohugoio/hashstructure v0.5.0
-       github.com/gohugoio/httpcache v0.7.0
+       github.com/gohugoio/httpcache v0.8.0
        github.com/gohugoio/hugo-goldmark-extensions/extras v0.5.0
        github.com/gohugoio/hugo-goldmark-extensions/passthrough v0.3.1
        github.com/gohugoio/locales v0.14.0
diff --git a/go.sum b/go.sum
index 16ef9c7c48aa48a9f81cf7577e586164312aa1a0..e93720d8e690138d6eb17558a898b51b6d8590e5 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -268,6 +268,8 @@ github.com/gohugoio/hashstructure v0.5.0 h1:G2fjSBU36RdwEJBWJ+919ERvOVqAg9tfcYp4
 github.com/gohugoio/hashstructure v0.5.0/go.mod h1:Ser0TniXuu/eauYmrwM4o64EBvySxNzITEOLlm4igec=
 github.com/gohugoio/httpcache v0.7.0 h1:ukPnn04Rgvx48JIinZvZetBfHaWE7I01JR2Q2RrQ3Vs=
 github.com/gohugoio/httpcache v0.7.0/go.mod h1:fMlPrdY/vVJhAriLZnrF5QpN3BNAcoBClgAyQd+lGFI=
+github.com/gohugoio/httpcache v0.8.0 h1:hNdsmGSELztetYCsPVgjA960zSa4dfEqqF/SficorCU=
+github.com/gohugoio/httpcache v0.8.0/go.mod h1:fMlPrdY/vVJhAriLZnrF5QpN3BNAcoBClgAyQd+lGFI=
 github.com/gohugoio/hugo-goldmark-extensions/extras v0.5.0 h1:dco+7YiOryRoPOMXwwaf+kktZSCtlFtreNdiJbETvYE=
 github.com/gohugoio/hugo-goldmark-extensions/extras v0.5.0/go.mod h1:CRrxQTKeM3imw+UoS4EHKyrqB7Zp6sAJiqHit+aMGTE=
 github.com/gohugoio/hugo-goldmark-extensions/passthrough v0.3.1 h1:nUzXfRTszLliZuN0JTKeunXTRaiFX6ksaWP0puLLYAY=
index 14b17a10552de22cf6a9a1f786630cda08b40150..e8a0b4c4db166ff748f8e43decdc27c7f0f654a9 100644 (file)
@@ -111,6 +111,19 @@ func New(rs *resources.Spec) *Client {
                                ShouldCache: func(req *http.Request, resp *http.Response, key string) bool {
                                        return shouldCache(resp.StatusCode)
                                },
+                               CanStore: func(reqCacheControl, respCacheControl httpcache.CacheControl) (canStore bool) {
+                                       if httpCacheConfig.Base.RespectCacheControlNoStoreInResponse {
+                                               if _, ok := respCacheControl["no-store"]; ok {
+                                                       return false
+                                               }
+                                       }
+                                       if httpCacheConfig.Base.RespectCacheControlNoStoreInRequest {
+                                               if _, ok := reqCacheControl["no-store"]; ok {
+                                                       return false
+                                               }
+                                       }
+                                       return true
+                               },
                                MarkCachedResponses: true,
                                EnableETagPair:      true,
                                Transport: &transport{