perf: cache generated image thumbnails

This commit is contained in:
OpenClaw Agent
2026-09-22 05:51:06 +08:00
parent f799104fb2
commit e6806de5f6
4 changed files with 225 additions and 27 deletions
+45 -27
View File
@@ -37,25 +37,27 @@ import (
var webIndex []byte
type Server struct {
Store storage.Storage
Auth *auth.Manager
Sessions map[string]*auth.Account
SessionExpiry map[string]time.Time
SessionMu sync.RWMutex
SessionTimeout int
JWTSecret string
WebDAVRoot string
WebDAVFS webdav.FileSystem
Allow string
MultiRoot bool
RemoveMode int
ImagePreview bool
FolderDownload string
HTMLTitle string
HTMLNotice string
Log *opslog.Logger
UserStore *auth.UserStore
UserHome string
Store storage.Storage
Auth *auth.Manager
Sessions map[string]*auth.Account
SessionExpiry map[string]time.Time
SessionMu sync.RWMutex
SessionTimeout int
JWTSecret string
WebDAVRoot string
WebDAVFS webdav.FileSystem
Allow string
MultiRoot bool
RemoveMode int
ImagePreview bool
FolderDownload string
HTMLTitle string
HTMLNotice string
Log *opslog.Logger
UserStore *auth.UserStore
UserHome string
ThumbnailCache *thumbnailCache
thumbnailCacheOnce sync.Once
}
type fileInfo struct {
Name string `json:"name"`
@@ -1176,20 +1178,36 @@ func (s *Server) thumbnail(w http.ResponseWriter, r *http.Request) {
return
}
defer f.Close()
src, _, err := image.Decode(f)
fi, err := f.Stat()
if err != nil {
http.NotFound(w, r)
return
}
key := thumbnailCacheKey{Path: file, Size: fi.Size(), ModTime: fi.ModTime().UnixNano()}
s.thumbnailCacheOnce.Do(func() {
if s.ThumbnailCache == nil {
s.ThumbnailCache = newThumbnailCache()
}
})
data, err := s.ThumbnailCache.Do(key, func() ([]byte, error) {
src, _, err := image.Decode(f)
if err != nil {
return nil, err
}
thumb := transform.Resize(src, 320, 240, transform.Linear)
var buf bytes.Buffer
if err := png.Encode(&buf, thumb); err != nil {
return nil, err
}
return append([]byte(nil), buf.Bytes()...), nil
})
if err != nil {
http.Error(w, "thumbnail unavailable", http.StatusUnsupportedMediaType)
return
}
thumb := transform.Resize(src, 320, 240, transform.Linear)
var buf bytes.Buffer
if err := png.Encode(&buf, thumb); err != nil {
http.Error(w, "thumbnail unavailable", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "image/png")
w.Header().Set("Cache-Control", "private, max-age=300")
_, _ = w.Write(buf.Bytes())
_, _ = w.Write(data)
}
func (s *Server) fileHandler(w http.ResponseWriter, r *http.Request) {