fix: align CHFS API response compatibility
This commit is contained in:
@@ -45,6 +45,7 @@ type fileInfo struct {
|
|||||||
Mask string `json:"mask"`
|
Mask string `json:"mask"`
|
||||||
GuestMask string `json:"guestMask"`
|
GuestMask string `json:"guestMask"`
|
||||||
HasSubDir bool `json:"hasSubDir"`
|
HasSubDir bool `json:"hasSubDir"`
|
||||||
|
Icon string `json:"icon"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Handler() http.Handler {
|
func (s *Server) Handler() http.Handler {
|
||||||
@@ -104,7 +105,7 @@ func clientIPString(r *http.Request) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func writeJSON(w http.ResponseWriter, v any) {
|
func writeJSON(w http.ResponseWriter, v any) {
|
||||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
json.NewEncoder(w).Encode(v)
|
json.NewEncoder(w).Encode(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,6 +129,33 @@ func permString(p auth.PermMask) string {
|
|||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
func iconFor(fi os.FileInfo) string {
|
||||||
|
if fi.IsDir() {
|
||||||
|
return "asset/icons/folder.svg"
|
||||||
|
}
|
||||||
|
ext := strings.ToLower(filepath.Ext(fi.Name()))
|
||||||
|
switch ext {
|
||||||
|
case ".txt", ".md", ".log", ".json", ".xml", ".yaml", ".yml", ".ini", ".conf", ".cfg":
|
||||||
|
return "asset/icons/txt.svg"
|
||||||
|
case ".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".svg":
|
||||||
|
return "asset/icons/image.svg"
|
||||||
|
case ".mp3", ".wav", ".flac", ".aac", ".m4a", ".ogg":
|
||||||
|
return "asset/icons/audio.svg"
|
||||||
|
case ".mp4", ".mkv", ".avi", ".mov", ".webm":
|
||||||
|
return "asset/icons/video.svg"
|
||||||
|
case ".zip", ".rar", ".7z", ".tar", ".gz":
|
||||||
|
return "asset/icons/archive.svg"
|
||||||
|
case ".pdf":
|
||||||
|
return "asset/icons/pdf.svg"
|
||||||
|
default:
|
||||||
|
return "asset/icons/unknown.svg"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func originalTime(t time.Time) string { return t.Format("2006-01-02 15:04:05") }
|
||||||
|
|
||||||
|
func writeCreated(w http.ResponseWriter) { w.WriteHeader(http.StatusCreated) }
|
||||||
|
|
||||||
func (s *Server) files(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) files(w http.ResponseWriter, r *http.Request) {
|
||||||
a := account(r, s)
|
a := account(r, s)
|
||||||
p := qpath(r)
|
p := qpath(r)
|
||||||
@@ -150,7 +178,7 @@ func (s *Server) files(w http.ResponseWriter, r *http.Request) {
|
|||||||
sub = len(xs) > 0
|
sub = len(xs) > 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out = append(out, fileInfo{Name: fi.Name(), Path: fp, Size: fi.Size(), Modified: fi.ModTime().Format(time.RFC3339), Dir: fi.IsDir(), Mask: permString(a.MaskFor(fp)), GuestMask: permString(s.Auth.Guest.MaskFor(fp)), HasSubDir: sub})
|
out = append(out, fileInfo{Name: fi.Name(), Path: fp, Size: fi.Size(), Modified: originalTime(fi.ModTime()), Dir: fi.IsDir(), Mask: permString(a.MaskFor(fp)), GuestMask: permString(s.Auth.Guest.MaskFor(fp)), HasSubDir: sub, Icon: iconFor(fi)})
|
||||||
}
|
}
|
||||||
virtual := p == "" && s.MultiRoot
|
virtual := p == "" && s.MultiRoot
|
||||||
writeJSON(w, map[string]any{"files": out, "currentMask": permString(m), "virtualRoot": virtual})
|
writeJSON(w, map[string]any{"files": out, "currentMask": permString(m), "virtualRoot": virtual})
|
||||||
@@ -182,7 +210,7 @@ func (s *Server) newdir(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.logOp(r, fmt.Sprintf("created directory '%s'", p))
|
s.logOp(r, fmt.Sprintf("created directory '%s'", p))
|
||||||
writeJSON(w, map[string]any{"ok": true})
|
writeCreated(w)
|
||||||
}
|
}
|
||||||
func (s *Server) rename(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) rename(w http.ResponseWriter, r *http.Request) {
|
||||||
a := account(r, s)
|
a := account(r, s)
|
||||||
@@ -197,7 +225,7 @@ func (s *Server) rename(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.logOp(r, fmt.Sprintf("renamed '%s' to '%s'", old, neu))
|
s.logOp(r, fmt.Sprintf("renamed '%s' to '%s'", old, neu))
|
||||||
writeJSON(w, map[string]any{"ok": true})
|
writeCreated(w)
|
||||||
}
|
}
|
||||||
func (s *Server) remove(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) remove(w http.ResponseWriter, r *http.Request) {
|
||||||
a := account(r, s)
|
a := account(r, s)
|
||||||
@@ -219,7 +247,7 @@ func (s *Server) remove(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
s.logOp(r, fmt.Sprintf("removed '%s'", strings.Trim(p, "/")))
|
s.logOp(r, fmt.Sprintf("removed '%s'", strings.Trim(p, "/")))
|
||||||
}
|
}
|
||||||
writeJSON(w, map[string]any{"ok": true})
|
w.WriteHeader(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
func (s *Server) removePath(p string) error {
|
func (s *Server) removePath(p string) error {
|
||||||
mode := s.RemoveMode
|
mode := s.RemoveMode
|
||||||
@@ -249,8 +277,13 @@ func (s *Server) removePath(p string) error {
|
|||||||
func (s *Server) exist(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) exist(w http.ResponseWriter, r *http.Request) {
|
||||||
p := strings.Trim(strings.ReplaceAll(r.URL.Query().Get("file"), "\\", "/"), "/")
|
p := strings.Trim(strings.ReplaceAll(r.URL.Query().Get("file"), "\\", "/"), "/")
|
||||||
_, e := s.Store.Stat(p)
|
_, e := s.Store.Stat(p)
|
||||||
writeJSON(w, map[string]any{"exist": e == nil})
|
if e != nil {
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
w.WriteHeader(http.StatusCreated)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) session(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) session(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method == http.MethodDelete {
|
if r.Method == http.MethodDelete {
|
||||||
jwtValue, _ := r.Cookie("JWT")
|
jwtValue, _ := r.Cookie("JWT")
|
||||||
@@ -317,7 +350,7 @@ func (s *Server) newtext(w http.ResponseWriter, r *http.Request) {
|
|||||||
defer f.Close()
|
defer f.Close()
|
||||||
io.WriteString(f, r.FormValue("text"))
|
io.WriteString(f, r.FormValue("text"))
|
||||||
s.logOp(r, fmt.Sprintf("create a text file:'%s'", p))
|
s.logOp(r, fmt.Sprintf("create a text file:'%s'", p))
|
||||||
writeJSON(w, map[string]any{"ok": true})
|
writeCreated(w)
|
||||||
}
|
}
|
||||||
func (s *Server) updatetext(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) updatetext(w http.ResponseWriter, r *http.Request) {
|
||||||
a := account(r, s)
|
a := account(r, s)
|
||||||
@@ -339,7 +372,7 @@ func (s *Server) updatetext(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.logOp(r, fmt.Sprintf("update text file:'%s'", p))
|
s.logOp(r, fmt.Sprintf("update text file:'%s'", p))
|
||||||
writeJSON(w, map[string]any{"ok": true})
|
writeCreated(w)
|
||||||
}
|
}
|
||||||
func (s *Server) upload(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) upload(w http.ResponseWriter, r *http.Request) {
|
||||||
if e := r.ParseMultipartForm(64 << 20); e != nil {
|
if e := r.ParseMultipartForm(64 << 20); e != nil {
|
||||||
@@ -370,8 +403,7 @@ func (s *Server) upload(w http.ResponseWriter, r *http.Request) {
|
|||||||
for _, name := range saved {
|
for _, name := range saved {
|
||||||
s.logOp(r, fmt.Sprintf("uploaded '%s'", filepath.Base(name)))
|
s.logOp(r, fmt.Sprintf("uploaded '%s'", filepath.Base(name)))
|
||||||
}
|
}
|
||||||
w.WriteHeader(http.StatusCreated)
|
writeCreated(w)
|
||||||
writeJSON(w, map[string]any{"ok": true, "files": saved})
|
|
||||||
}
|
}
|
||||||
func savePart(st storage.Storage, target string, h *multipart.FileHeader) error {
|
func savePart(st storage.Storage, target string, h *multipart.FileHeader) error {
|
||||||
in, e := h.Open()
|
in, e := h.Open()
|
||||||
@@ -415,21 +447,17 @@ func (s *Server) upload2(w http.ResponseWriter, r *http.Request) {
|
|||||||
saved = append(saved, path.Join(dir, name))
|
saved = append(saved, path.Join(dir, name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.WriteHeader(http.StatusCreated)
|
writeCreated(w)
|
||||||
writeJSON(w, map[string]any{"ok": true, "files": saved})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) search(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) search(w http.ResponseWriter, r *http.Request) {
|
||||||
a := account(r, s)
|
a := account(r, s)
|
||||||
if !a.MaskFor("").HasRead() {
|
rootMask := a.MaskFor("")
|
||||||
|
if !rootMask.HasRead() {
|
||||||
http.Error(w, "forbidden", 403)
|
http.Error(w, "forbidden", 403)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
needle := strings.ToLower(strings.TrimSpace(r.URL.Query().Get("str")))
|
needle := strings.ToLower(strings.TrimSpace(r.URL.Query().Get("str")))
|
||||||
if needle == "" {
|
|
||||||
writeJSON(w, map[string]any{"files": []fileInfo{}})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var out []fileInfo
|
var out []fileInfo
|
||||||
var walk func(string) error
|
var walk func(string) error
|
||||||
walk = func(dir string) error {
|
walk = func(dir string) error {
|
||||||
@@ -442,8 +470,8 @@ func (s *Server) search(w http.ResponseWriter, r *http.Request) {
|
|||||||
if !a.MaskFor(p).HasRead() {
|
if !a.MaskFor(p).HasRead() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if strings.Contains(strings.ToLower(fi.Name()), needle) {
|
if needle == "" || strings.Contains(strings.ToLower(fi.Name()), needle) {
|
||||||
out = append(out, fileInfo{Name: fi.Name(), Path: p, Size: fi.Size(), Modified: fi.ModTime().Format(time.RFC3339), Dir: fi.IsDir(), Mask: permString(a.MaskFor(p)), GuestMask: permString(s.Auth.Guest.MaskFor(p))})
|
out = append(out, fileInfo{Name: fi.Name(), Path: "/" + strings.Trim(p, "/"), Size: fi.Size(), Modified: originalTime(fi.ModTime()), Dir: fi.IsDir(), Mask: permString(a.MaskFor(p)), GuestMask: permString(s.Auth.Guest.MaskFor(p)), HasSubDir: false, Icon: iconFor(fi)})
|
||||||
}
|
}
|
||||||
if fi.IsDir() {
|
if fi.IsDir() {
|
||||||
if err := walk(p); err != nil {
|
if err := walk(p); err != nil {
|
||||||
@@ -457,8 +485,9 @@ func (s *Server) search(w http.ResponseWriter, r *http.Request) {
|
|||||||
http.Error(w, err.Error(), 500)
|
http.Error(w, err.Error(), 500)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
writeJSON(w, map[string]any{"files": out})
|
writeJSON(w, map[string]any{"virtualRoot": 0, "currentMask": permString(rootMask), "files": out})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) shared(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) shared(w http.ResponseWriter, r *http.Request) {
|
||||||
file := strings.Trim(r.URL.Query().Get("file"), "/")
|
file := strings.Trim(r.URL.Query().Get("file"), "/")
|
||||||
if file == "" {
|
if file == "" {
|
||||||
|
|||||||
Reference in New Issue
Block a user