mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-30 22:39:58 +02:00
@@ -23,6 +23,9 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/bep/logg"
|
||||
"github.com/gohugoio/httpcache"
|
||||
hhttpcache "github.com/gohugoio/hugo/cache/httpcache"
|
||||
"github.com/gohugoio/hugo/helpers"
|
||||
"github.com/gohugoio/hugo/hugofs/glob"
|
||||
"github.com/gohugoio/hugo/identity"
|
||||
@@ -31,7 +34,9 @@ import (
|
||||
|
||||
"github.com/gohugoio/hugo/cache/dynacache"
|
||||
"github.com/gohugoio/hugo/cache/filecache"
|
||||
"github.com/gohugoio/hugo/common/hcontext"
|
||||
"github.com/gohugoio/hugo/common/hugio"
|
||||
"github.com/gohugoio/hugo/common/tasks"
|
||||
"github.com/gohugoio/hugo/resources"
|
||||
"github.com/gohugoio/hugo/resources/resource"
|
||||
)
|
||||
@@ -39,19 +44,76 @@ import (
|
||||
// Client contains methods to create Resource objects.
|
||||
// tasks to Resource objects.
|
||||
type Client struct {
|
||||
rs *resources.Spec
|
||||
httpClient *http.Client
|
||||
cacheGetResource *filecache.Cache
|
||||
rs *resources.Spec
|
||||
httpClient *http.Client
|
||||
httpCacheConfig hhttpcache.ConfigCompiled
|
||||
cacheGetResource *filecache.Cache
|
||||
resourceIDDispatcher hcontext.ContextDispatcher[string]
|
||||
|
||||
// Set when watching.
|
||||
remoteResourceChecker *tasks.RunEvery
|
||||
remoteResourceLogger logg.LevelLogger
|
||||
}
|
||||
|
||||
type contextKey string
|
||||
|
||||
// New creates a new Client with the given specification.
|
||||
func New(rs *resources.Spec) *Client {
|
||||
fileCache := rs.FileCaches.GetResourceCache()
|
||||
resourceIDDispatcher := hcontext.NewContextDispatcher[string](contextKey("resourceID"))
|
||||
httpCacheConfig := rs.Cfg.GetConfigSection("httpCacheCompiled").(hhttpcache.ConfigCompiled)
|
||||
var remoteResourceChecker *tasks.RunEvery
|
||||
if rs.Cfg.Watching() && !httpCacheConfig.IsPollingDisabled() {
|
||||
remoteResourceChecker = &tasks.RunEvery{
|
||||
HandleError: func(name string, err error) {
|
||||
rs.Logger.Warnf("Failed to check remote resource: %s", err)
|
||||
},
|
||||
RunImmediately: false,
|
||||
}
|
||||
|
||||
if err := remoteResourceChecker.Start(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
rs.BuildClosers.Add(remoteResourceChecker)
|
||||
}
|
||||
|
||||
httpTimeout := 2 * time.Minute // Need to cover retries.
|
||||
if httpTimeout < (rs.Cfg.Timeout() + 30*time.Second) {
|
||||
httpTimeout = rs.Cfg.Timeout() + 30*time.Second
|
||||
}
|
||||
|
||||
return &Client{
|
||||
rs: rs,
|
||||
rs: rs,
|
||||
httpCacheConfig: httpCacheConfig,
|
||||
resourceIDDispatcher: resourceIDDispatcher,
|
||||
remoteResourceChecker: remoteResourceChecker,
|
||||
remoteResourceLogger: rs.Logger.InfoCommand("remote"),
|
||||
httpClient: &http.Client{
|
||||
Timeout: time.Minute,
|
||||
Timeout: httpTimeout,
|
||||
Transport: &httpcache.Transport{
|
||||
Cache: fileCache.AsHTTPCache(),
|
||||
CacheKey: func(req *http.Request) string {
|
||||
return resourceIDDispatcher.Get(req.Context())
|
||||
},
|
||||
Around: func(req *http.Request, key string) func() {
|
||||
return fileCache.NamedLock(key)
|
||||
},
|
||||
AlwaysUseCachedResponse: func(req *http.Request, key string) bool {
|
||||
return !httpCacheConfig.For(req.URL.String())
|
||||
},
|
||||
ShouldCache: func(req *http.Request, resp *http.Response, key string) bool {
|
||||
return shouldCache(resp.StatusCode)
|
||||
},
|
||||
MarkCachedResponses: true,
|
||||
EnableETagPair: true,
|
||||
Transport: &transport{
|
||||
Cfg: rs.Cfg,
|
||||
Logger: rs.Logger,
|
||||
},
|
||||
},
|
||||
},
|
||||
cacheGetResource: rs.FileCaches.GetResourceCache(),
|
||||
cacheGetResource: fileCache,
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user