mirror of
https://github.com/selfhst/icons.git
synced 2026-04-30 13:26:18 -04:00
v4.0.1 (CACHE_TTL fix)
This commit is contained in:
@@ -1,3 +1,10 @@
|
|||||||
|
# v4.0.1
|
||||||
|
|
||||||
|
## What's Changed
|
||||||
|
|
||||||
|
* Replaced hard-coded cache age values with the `CACHE_TTL` variable added in v4.0.0 ([#748](https://github.com/selfhst/icons/issues/748))
|
||||||
|
* Updated background routine to periodically purge stale assets based on `CACHE_TTL` time
|
||||||
|
|
||||||
# v4.0.0
|
# v4.0.0
|
||||||
|
|
||||||
This release initially set out to address a request to support icon extensions in URLs, but quickly grew into a number of under the hood optimization/security fixes and a new ```hybrid``` mode that allows users with local collections to set remote icons as a fallback.
|
This release initially set out to address a request to support icon extensions in URLs, but quickly grew into a number of under the hood optimization/security fixes and a new ```hybrid``` mode that allows users with local collections to set remote icons as a fallback.
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
4.0.0
|
4.0.1
|
||||||
@@ -79,6 +79,16 @@ func (c *Cache) Get(key string) (string, bool) {
|
|||||||
return item.Content, true
|
return item.Content, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Cache) cleanup() {
|
||||||
|
c.mutex.Lock()
|
||||||
|
defer c.mutex.Unlock()
|
||||||
|
for k, v := range c.items {
|
||||||
|
if time.Since(v.Timestamp) > c.ttl {
|
||||||
|
delete(c.items, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Cache) Set(key, value string) {
|
func (c *Cache) Set(key, value string) {
|
||||||
c.mutex.Lock()
|
c.mutex.Lock()
|
||||||
defer c.mutex.Unlock()
|
defer c.mutex.Unlock()
|
||||||
@@ -432,7 +442,7 @@ func handleIcon(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Header().Set("Content-Type", contentType)
|
w.Header().Set("Content-Type", contentType)
|
||||||
w.Header().Set("Cache-Control", "public, max-age=3600")
|
w.Header().Set("Cache-Control", fmt.Sprintf("public, max-age=%d", int(config.CacheTTL.Seconds())))
|
||||||
w.Header().Set("ETag", etag)
|
w.Header().Set("ETag", etag)
|
||||||
w.Header().Set("X-Cache", "HIT")
|
w.Header().Set("X-Cache", "HIT")
|
||||||
serveContent(w, r, contentType, cached)
|
serveContent(w, r, contentType, cached)
|
||||||
@@ -525,7 +535,7 @@ func handleIcon(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Header().Set("Content-Type", contentType)
|
w.Header().Set("Content-Type", contentType)
|
||||||
w.Header().Set("Cache-Control", "public, max-age=3600")
|
w.Header().Set("Cache-Control", fmt.Sprintf("public, max-age=%d", int(config.CacheTTL.Seconds())))
|
||||||
w.Header().Set("ETag", etag)
|
w.Header().Set("ETag", etag)
|
||||||
w.Header().Set("X-Cache", "MISS")
|
w.Header().Set("X-Cache", "MISS")
|
||||||
serveContent(w, r, contentType, iconContent)
|
serveContent(w, r, contentType, iconContent)
|
||||||
@@ -578,6 +588,7 @@ func handleCustomIcon(w http.ResponseWriter, r *http.Request) {
|
|||||||
if cached, found := cache.Get(cacheKey); found {
|
if cached, found := cache.Get(cacheKey); found {
|
||||||
logf(logLevelDebug, "[CACHE] Serving cached custom icon: \"%s\" %v", filename, formatDuration(time.Since(start)))
|
logf(logLevelDebug, "[CACHE] Serving cached custom icon: \"%s\" %v", filename, formatDuration(time.Since(start)))
|
||||||
w.Header().Set("Content-Type", contentType)
|
w.Header().Set("Content-Type", contentType)
|
||||||
|
w.Header().Set("Cache-Control", fmt.Sprintf("public, max-age=%d", int(config.CacheTTL.Seconds())))
|
||||||
w.Header().Set("ETag", etag)
|
w.Header().Set("ETag", etag)
|
||||||
w.Header().Set("X-Cache", "HIT")
|
w.Header().Set("X-Cache", "HIT")
|
||||||
serveContent(w, r, contentType, cached)
|
serveContent(w, r, contentType, cached)
|
||||||
@@ -596,6 +607,7 @@ func handleCustomIcon(w http.ResponseWriter, r *http.Request) {
|
|||||||
logf(logLevelInfo, "[SUCCESS] Serving custom icon: \"%s\" (%s) %v", filename, contentType, formatDuration(time.Since(start)))
|
logf(logLevelInfo, "[SUCCESS] Serving custom icon: \"%s\" (%s) %v", filename, contentType, formatDuration(time.Since(start)))
|
||||||
|
|
||||||
w.Header().Set("Content-Type", contentType)
|
w.Header().Set("Content-Type", contentType)
|
||||||
|
w.Header().Set("Cache-Control", fmt.Sprintf("public, max-age=%d", int(config.CacheTTL.Seconds())))
|
||||||
w.Header().Set("ETag", etag)
|
w.Header().Set("ETag", etag)
|
||||||
w.Header().Set("X-Cache", "MISS")
|
w.Header().Set("X-Cache", "MISS")
|
||||||
serveContent(w, r, contentType, string(data))
|
serveContent(w, r, contentType, string(data))
|
||||||
@@ -660,6 +672,20 @@ func main() {
|
|||||||
quit := make(chan os.Signal, 1)
|
quit := make(chan os.Signal, 1)
|
||||||
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
|
||||||
|
cleanupCtx, cleanupCancel := context.WithCancel(context.Background())
|
||||||
|
go func() {
|
||||||
|
ticker := time.NewTicker(config.CacheTTL)
|
||||||
|
defer ticker.Stop()
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ticker.C:
|
||||||
|
cache.cleanup()
|
||||||
|
case <-cleanupCtx.Done():
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||||
log.Fatalf("Server error: %v", err)
|
log.Fatalf("Server error: %v", err)
|
||||||
@@ -667,6 +693,7 @@ func main() {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
<-quit
|
<-quit
|
||||||
|
cleanupCancel()
|
||||||
log.Println("Shutting down...")
|
log.Println("Shutting down...")
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
|||||||
Reference in New Issue
Block a user