fix: match CHFS preview and listing behavior
This commit is contained in:
@@ -89,7 +89,7 @@ func main() {
|
||||
if len(cfg.Path) == 1 {
|
||||
store = storage.Local{Root: root}
|
||||
}
|
||||
srv := &api.Server{Store: store, Auth: mgr, Sessions: map[string]*auth.Account{}, SessionExpiry: map[string]time.Time{}, SessionTimeout: cfg.SessionTimeout, WebDAVRoot: root, Allow: cfg.Allow, MultiRoot: len(cfg.Path) > 1, RemoveMode: cfg.FileRemove, Log: opslog.New(cfg.Log)}
|
||||
srv := &api.Server{Store: store, Auth: mgr, Sessions: map[string]*auth.Account{}, SessionExpiry: map[string]time.Time{}, SessionTimeout: cfg.SessionTimeout, WebDAVRoot: root, Allow: cfg.Allow, MultiRoot: len(cfg.Path) > 1, RemoveMode: cfg.FileRemove, ImagePreview: cfg.ImagePreview, Log: opslog.New(cfg.Log)}
|
||||
addr := ":" + itoa(cfg.Port)
|
||||
log.Printf("chfs-ng listening on %s root=%s removeMode=%d", addr, filepath.Clean(root), cfg.FileRemove)
|
||||
if cfg.SSLCert != "" && cfg.SSLKey != "" {
|
||||
|
||||
@@ -4,6 +4,7 @@ go 1.22
|
||||
|
||||
require (
|
||||
github.com/Bios-Marcel/wastebasket v0.0.3
|
||||
github.com/anthonynsimon/bild v0.14.0
|
||||
github.com/emersion/go-webdav v0.7.0
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2
|
||||
)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
github.com/Bios-Marcel/wastebasket v0.0.3 h1:gyuMcoDav6n+sdynn9TDl1NN7GOAnoy227JErVSW3RM=
|
||||
github.com/Bios-Marcel/wastebasket v0.0.3/go.mod h1:FChzXi1izqzdPb6BiNZmcZLGyTYiT61iGx9Rxx9GNeI=
|
||||
github.com/anthonynsimon/bild v0.14.0 h1:IFRkmKdNdqmexXHfEU7rPlAmdUZ8BDZEGtGHDnGWync=
|
||||
github.com/anthonynsimon/bild v0.14.0/go.mod h1:hcvEAyBjTW69qkKJTfpcDQ83sSZHxwOunsseDfeQhUs=
|
||||
github.com/emersion/go-ical v0.0.0-20240127095438-fc1c9d8fb2b6/go.mod h1:BEksegNspIkjCQfmzWgsgbu6KdeJ/4LwUZs7DMBzjzw=
|
||||
github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9/go.mod h1:HMJKR5wlh/ziNp+sHEDV2ltblO4JD2+IdDOWtGcQBTM=
|
||||
github.com/emersion/go-webdav v0.7.0 h1:cp6aBWXBf8Sjzguka9VJarr4XTkGc2IHxXI1Gq3TKpA=
|
||||
|
||||
@@ -2,9 +2,14 @@ package api
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"image"
|
||||
_ "image/gif"
|
||||
_ "image/jpeg"
|
||||
"image/png"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net"
|
||||
@@ -19,6 +24,7 @@ import (
|
||||
"chfs-ng/internal/auth"
|
||||
"chfs-ng/internal/opslog"
|
||||
"chfs-ng/internal/storage"
|
||||
"github.com/anthonynsimon/bild/transform"
|
||||
"github.com/emersion/go-webdav"
|
||||
)
|
||||
|
||||
@@ -34,6 +40,7 @@ type Server struct {
|
||||
Allow string
|
||||
MultiRoot bool
|
||||
RemoveMode int
|
||||
ImagePreview bool
|
||||
Log *opslog.Logger
|
||||
}
|
||||
type fileInfo struct {
|
||||
@@ -463,7 +470,7 @@ func (s *Server) search(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
needle := strings.ToLower(strings.TrimSpace(r.URL.Query().Get("str")))
|
||||
var out []fileInfo
|
||||
out := make([]fileInfo, 0)
|
||||
var walk func(string) error
|
||||
walk = func(dir string) error {
|
||||
items, err := s.Store.List(dir)
|
||||
@@ -502,16 +509,39 @@ func (s *Server) shared(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (s *Server) preview(w http.ResponseWriter, r *http.Request) {
|
||||
if !account(r, s).MaskFor(strings.Trim(r.URL.Query().Get("file"), "/")).HasRead() {
|
||||
http.Error(w, "forbidden", 403)
|
||||
return
|
||||
}
|
||||
file := strings.Trim(r.URL.Query().Get("file"), "/")
|
||||
file := strings.Trim(strings.ReplaceAll(r.URL.Query().Get("file"), "\\", "/"), "/")
|
||||
if file == "" {
|
||||
http.Error(w, "file required", 400)
|
||||
return
|
||||
}
|
||||
s.serveFile(w, r, file, false)
|
||||
if !account(r, s).MaskFor(file).HasRead() {
|
||||
http.Error(w, "forbidden", 403)
|
||||
return
|
||||
}
|
||||
if !s.ImagePreview {
|
||||
writeJSONError(w, http.StatusInternalServerError, "Open image file fail!")
|
||||
return
|
||||
}
|
||||
f, err := s.Store.Open(file)
|
||||
if err != nil {
|
||||
writeJSONError(w, http.StatusInternalServerError, "Open image file fail!")
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
src, _, err := image.Decode(f)
|
||||
if err != nil {
|
||||
writeJSONError(w, http.StatusInternalServerError, "Open image file fail!")
|
||||
return
|
||||
}
|
||||
thumb := transform.Resize(src, 64, 64, transform.Linear)
|
||||
var buf bytes.Buffer
|
||||
if err := png.Encode(&buf, thumb); err != nil {
|
||||
writeJSONError(w, http.StatusInternalServerError, "Open image file fail!")
|
||||
return
|
||||
}
|
||||
w.Header().Set("Cache-Control", "max-age=2592000")
|
||||
w.Header().Set("Content-Type", "image/png")
|
||||
_, _ = w.Write(buf.Bytes())
|
||||
}
|
||||
|
||||
func (s *Server) fileHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
@@ -258,7 +259,12 @@ func (s Local) List(path string) ([]os.FileInfo, error) {
|
||||
return nil, e
|
||||
}
|
||||
defer f.Close()
|
||||
return f.Readdir(-1)
|
||||
items, err := f.Readdir(-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sort.Slice(items, func(i, j int) bool { return items[i].Name() < items[j].Name() })
|
||||
return items, nil
|
||||
}
|
||||
|
||||
var _ fs.FS
|
||||
|
||||
Reference in New Issue
Block a user