feat(files): add folder download as zip
- Add zip folder API endpoint - Add download button to folder rows - Enforce max archive size limit - Document endpoint in OpenAPI
This commit is contained in:
@@ -135,6 +135,62 @@ func (a *Agent) deleteFile(w http.ResponseWriter, r *http.Request) {
|
||||
helpers.WriteJSON(w, http.StatusOK, map[string]any{"ok": true, "path": path})
|
||||
}
|
||||
|
||||
func (a *Agent) handleZipFolder(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
helpers.WriteError(w, http.StatusMethodNotAllowed, "method not allowed")
|
||||
return
|
||||
}
|
||||
path := r.URL.Query().Get("path")
|
||||
if path == "" {
|
||||
helpers.WriteError(w, http.StatusBadRequest, "path is required")
|
||||
return
|
||||
}
|
||||
dir, err := files.AllowedPath(a.root, path, true)
|
||||
if err != nil {
|
||||
files.WritePathError(w, err)
|
||||
return
|
||||
}
|
||||
info, err := os.Stat(dir)
|
||||
if err != nil {
|
||||
files.WritePathError(w, err)
|
||||
return
|
||||
}
|
||||
if !info.IsDir() {
|
||||
helpers.WriteError(w, http.StatusBadRequest, "path is not a directory")
|
||||
return
|
||||
}
|
||||
|
||||
zipPath, err := files.ZipDirectory(dir, config.MaxUploadSize)
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, files.ErrZipTooLarge):
|
||||
helpers.WriteError(w, http.StatusRequestEntityTooLarge, err.Error())
|
||||
default:
|
||||
helpers.Log.Printf("zip folder: %v", err)
|
||||
files.WritePathError(w, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
defer os.Remove(zipPath)
|
||||
|
||||
f, err := os.Open(zipPath)
|
||||
if err != nil {
|
||||
helpers.Log.Printf("zip open: %v", err)
|
||||
helpers.WriteError(w, http.StatusInternalServerError, "could not read archive")
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
zipInfo, err := f.Stat()
|
||||
if err != nil {
|
||||
helpers.WriteError(w, http.StatusInternalServerError, "could not read archive")
|
||||
return
|
||||
}
|
||||
name := files.ZipArchiveName(dir)
|
||||
w.Header().Set("Content-Type", "application/zip")
|
||||
w.Header().Set("Content-Disposition", `attachment; filename="`+strings.ReplaceAll(name, `"`, "'")+`"`)
|
||||
http.ServeContent(w, r, name, zipInfo.ModTime(), f)
|
||||
}
|
||||
|
||||
func (a *Agent) handleDownload(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
helpers.WriteError(w, http.StatusMethodNotAllowed, "method not allowed")
|
||||
|
||||
Reference in New Issue
Block a user