From a1704ca53b2b630ca700cf355ce9e67af1272c13 Mon Sep 17 00:00:00 2001 From: BuckarooBanzay Date: Tue, 23 Jul 2024 10:21:40 +0200 Subject: [PATCH] download single db-files as snapshot too --- web/filebrowser_download.go | 65 ++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/web/filebrowser_download.go b/web/filebrowser_download.go index e272900c..e7cfa57d 100644 --- a/web/filebrowser_download.go +++ b/web/filebrowser_download.go @@ -16,6 +16,32 @@ import ( "strings" ) +func ignoreFileDownload(filename string) bool { + if strings.HasSuffix(filename, ".sqlite-shm") || strings.HasSuffix(filename, ".sqlite-wal") { + // sqlite wal and shared memory + return true + } + return false +} + +func isSqliteDatabase(filename string) bool { + return strings.HasSuffix(filename, ".sqlite") +} + +func createSqliteSnapshot(filename string) (string, error) { + f, err := os.CreateTemp(os.TempDir(), "backup.sqlite") + if err != nil { + return "", fmt.Errorf("create temp error: %v", err) + } + + err = db.BackupSqlite3Database(context.Background(), filename, f.Name()) + if err != nil { + return "", fmt.Errorf("backup error from '%s' to '%s': %v", filename, f.Name(), err) + } + + return f.Name(), nil +} + func (a *Api) DownloadFile(w http.ResponseWriter, r *http.Request, claims *types.Claims) { rel_filename, filename, err := a.get_sanitized_filename(r, "filename") if err != nil { @@ -23,6 +49,17 @@ func (a *Api) DownloadFile(w http.ResponseWriter, r *http.Request, claims *types return } + maintenance := a.app.MaintenanceMode.Load() + if isSqliteDatabase(filename) && !maintenance { + tmppath, err := createSqliteSnapshot(filename) + if err != nil { + SendError(w, 500, fmt.Sprintf("error creating snapshot of '%s': %v", filename, err)) + return + } + defer os.Remove(tmppath) + filename = tmppath + } + f, err := os.Open(filename) if err != nil { SendError(w, 500, err.Error()) @@ -40,7 +77,7 @@ func (a *Api) DownloadFile(w http.ResponseWriter, r *http.Request, claims *types w.Header().Set("Content-Type", contentType) if r.URL.Query().Get("download") == "true" { - w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", path.Base(filename))) + w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", path.Base(rel_filename))) } _, err = w.Write(header[:header_size]) @@ -62,32 +99,6 @@ func (a *Api) DownloadFile(w http.ResponseWriter, r *http.Request, claims *types }, r) } -func ignoreFileDownload(filename string) bool { - if strings.HasSuffix(filename, ".sqlite-shm") || strings.HasSuffix(filename, ".sqlite-wal") { - // sqlite wal and shared memory - return true - } - return false -} - -func isSqliteDatabase(filename string) bool { - return strings.HasSuffix(filename, ".sqlite") -} - -func createSqliteSnapshot(filename string) (string, error) { - f, err := os.CreateTemp(os.TempDir(), "backup.sqlite") - if err != nil { - return "", fmt.Errorf("create temp error: %v", err) - } - - err = db.BackupSqlite3Database(context.Background(), filename, f.Name()) - if err != nil { - return "", fmt.Errorf("backup error from '%s' to '%s': %v", filename, f.Name(), err) - } - - return f.Name(), nil -} - func (a *Api) DownloadZip(w http.ResponseWriter, r *http.Request, claims *types.Claims) { maintenance := a.app.MaintenanceMode.Load()