diff --git a/chfs-ng/internal/api/server.go b/chfs-ng/internal/api/server.go index ae87e74..66115b4 100644 --- a/chfs-ng/internal/api/server.go +++ b/chfs-ng/internal/api/server.go @@ -6,6 +6,7 @@ import ( "context" "encoding/json" "fmt" + "html" "image" _ "image/gif" _ "image/jpeg" @@ -14,6 +15,7 @@ import ( "mime/multipart" "net" "net/http" + "net/url" "os" "path" "path/filepath" @@ -71,6 +73,7 @@ func (s *Server) Handler() http.Handler { mux.HandleFunc("/chfs/search", s.search) mux.HandleFunc("/chfs/downloaddir/", s.downloadDir) mux.HandleFunc("/chfs/shared", s.shared) + mux.HandleFunc("/chfs/shared/", s.shared) mux.HandleFunc("/chfs/preview", s.preview) mux.HandleFunc("/", s.fileHandler) return s.ipFilter(mux) @@ -510,11 +513,53 @@ func (s *Server) search(w http.ResponseWriter, r *http.Request) { } func (s *Server) shared(w http.ResponseWriter, r *http.Request) { - file := strings.Trim(r.URL.Query().Get("file"), "/") - if file == "" { - file = strings.TrimPrefix(r.URL.Path, "/chfs/shared/") + if r.URL.Path == "/chfs/shared" { + location := "shared/" + if r.URL.RawQuery != "" { + location += "?" + r.URL.RawQuery + } + http.Redirect(w, r, location, http.StatusMovedPermanently) + return } - s.serveFile(w, r, file, true) + p := strings.Trim(strings.TrimPrefix(r.URL.Path, "/chfs/shared/"), "/") + fi, err := s.Store.Stat(p) + if err != nil { + http.NotFound(w, r) + return + } + if fi.IsDir() { + items, err := s.Store.List(p) + if err != nil { + http.NotFound(w, r) + return + } + w.Header().Set("Content-Disposition", `attachment;filename="shared"`) + w.Header().Set("Content-Type", "text/html; charset=utf-8") + _, _ = io.WriteString(w, "
\n")
+ for _, item := range items {
+ name := item.Name()
+ href := url.PathEscape(name)
+ if item.IsDir() {
+ href += "/"
+ }
+ _, _ = fmt.Fprintf(w, "%s\n", href, html.EscapeString(name)+func() string {
+ if item.IsDir() {
+ return "/"
+ }
+ return ""
+ }())
+ }
+ _, _ = io.WriteString(w, "\n")
+ return
+ }
+ f, err := s.Store.Open(p)
+ if err != nil {
+ http.NotFound(w, r)
+ return
+ }
+ defer f.Close()
+ w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment;filename="%s"`, fi.Name()))
+ http.ServeContent(w, r, fi.Name(), fi.ModTime(), f)
}
func (s *Server) preview(w http.ResponseWriter, r *http.Request) {