perf: cache generated image thumbnails
This commit is contained in:
+45
-27
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user