feat: update WebDAV download handler to support range requests and improve response handling

This commit is contained in:
Leon Bösche
2026-01-11 14:38:03 +01:00
parent b2e5eef66f
commit 5ef5623c8d
2 changed files with 46 additions and 19 deletions

View File

@@ -1418,13 +1418,13 @@ func downloadOrgFileHandler(w http.ResponseWriter, r *http.Request, db *database
// Download from user's Nextcloud space under /orgs/<orgID>/
rel := strings.TrimPrefix(filePath, "/")
remotePath := path.Join("/orgs", orgID.String(), rel)
reader, size, err := storageClient.Download(r.Context(), remotePath)
resp, err := storageClient.Download(r.Context(), remotePath, r.Header.Get("Range"))
if err != nil {
errors.LogError(r, err, "Failed to download from Nextcloud")
errors.WriteError(w, errors.CodeNotFound, "File not found", http.StatusNotFound)
return
}
defer reader.Close()
defer resp.Body.Close()
// Set appropriate headers for inline viewing
fileName := path.Base(filePath)
@@ -1438,13 +1438,25 @@ func downloadOrgFileHandler(w http.ResponseWriter, r *http.Request, db *database
contentType = "image/jpeg"
}
w.Header().Set("Content-Disposition", fmt.Sprintf("inline; filename=\"%s\"", fileName))
w.Header().Set("Content-Type", contentType)
if size > 0 {
w.Header().Set("Content-Length", fmt.Sprintf("%d", size))
if ct := resp.Header.Get("Content-Type"); ct != "" {
w.Header().Set("Content-Type", ct)
} else {
w.Header().Set("Content-Type", contentType)
}
w.Header().Set("Accept-Ranges", "bytes")
if cr := resp.Header.Get("Content-Range"); cr != "" {
w.Header().Set("Content-Range", cr)
}
if cl := resp.Header.Get("Content-Length"); cl != "" {
w.Header().Set("Content-Length", cl)
}
if resp.StatusCode == http.StatusPartialContent {
w.WriteHeader(http.StatusPartialContent)
}
// Stream the file
io.Copy(w, reader)
io.Copy(w, resp.Body)
}
@@ -1481,13 +1493,13 @@ func downloadUserFileHandler(w http.ResponseWriter, r *http.Request, db *databas
remotePath := strings.TrimPrefix(filePath, "/")
fmt.Printf("[DEBUG] Downloading from user WebDAV: /%s\n", remotePath)
reader, size, err := storageClient.Download(r.Context(), "/"+remotePath)
resp, err := storageClient.Download(r.Context(), "/"+remotePath, r.Header.Get("Range"))
if err != nil {
errors.LogError(r, err, "Failed to download from Nextcloud")
errors.WriteError(w, errors.CodeNotFound, "File not found", http.StatusNotFound)
return
}
defer reader.Close()
defer resp.Body.Close()
// Set appropriate headers for inline viewing
fileName := path.Base(filePath)
@@ -1501,12 +1513,24 @@ func downloadUserFileHandler(w http.ResponseWriter, r *http.Request, db *databas
contentType = "image/jpeg"
}
w.Header().Set("Content-Disposition", fmt.Sprintf("inline; filename=\"%s\"", fileName))
w.Header().Set("Content-Type", contentType)
if size > 0 {
w.Header().Set("Content-Length", fmt.Sprintf("%d", size))
if ct := resp.Header.Get("Content-Type"); ct != "" {
w.Header().Set("Content-Type", ct)
} else {
w.Header().Set("Content-Type", contentType)
}
w.Header().Set("Accept-Ranges", "bytes")
if cr := resp.Header.Get("Content-Range"); cr != "" {
w.Header().Set("Content-Range", cr)
}
if cl := resp.Header.Get("Content-Length"); cl != "" {
w.Header().Set("Content-Length", cl)
}
if resp.StatusCode == http.StatusPartialContent {
w.WriteHeader(http.StatusPartialContent)
}
// Stream the file
io.Copy(w, reader)
io.Copy(w, resp.Body)
}