From e3c5cf981fa1a4dad265be677133ac2c51118cd7 Mon Sep 17 00:00:00 2001 From: Nicola Murino Date: Tue, 26 Jul 2022 18:24:17 +0200 Subject: [PATCH] download as zip: improve filename include username and also filename/directory name if the user downloads a single file/directory Signed-off-by: Nicola Murino --- internal/httpd/api_http_user.go | 3 ++- internal/httpd/api_utils.go | 8 ++++++++ internal/httpd/internal_test.go | 17 +++++++++++++++++ internal/httpd/webclient.go | 3 ++- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/internal/httpd/api_http_user.go b/internal/httpd/api_http_user.go index 9fd7cbd9..376c828e 100644 --- a/internal/httpd/api_http_user.go +++ b/internal/httpd/api_http_user.go @@ -390,7 +390,8 @@ func getUserFilesAsZipStream(w http.ResponseWriter, r *http.Request) { filesList = util.RemoveDuplicates(filesList, false) - w.Header().Set("Content-Disposition", "attachment; filename=\"sftpgo-download.zip\"") + w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", + getCompressedFileName(connection.GetUsername(), filesList))) renderCompressedFiles(w, connection, baseDir, filesList, nil) } diff --git a/internal/httpd/api_utils.go b/internal/httpd/api_utils.go index 55ec124c..51410918 100644 --- a/internal/httpd/api_utils.go +++ b/internal/httpd/api_utils.go @@ -221,6 +221,14 @@ func renderAPIDirContents(w http.ResponseWriter, r *http.Request, contents []os. render.JSON(w, r, results) } +func getCompressedFileName(username string, files []string) string { + if len(files) == 1 { + name := path.Base(files[0]) + return fmt.Sprintf("%s-%s.zip", username, strings.TrimSuffix(name, path.Ext(name))) + } + return fmt.Sprintf("%s-download.zip", username) +} + func renderCompressedFiles(w http.ResponseWriter, conn *Connection, baseDir string, files []string, share *dataprovider.Share, ) { diff --git a/internal/httpd/internal_test.go b/internal/httpd/internal_test.go index 0567b636..26cb127f 100644 --- a/internal/httpd/internal_test.go +++ b/internal/httpd/internal_test.go @@ -2531,6 +2531,23 @@ func TestSecureMiddlewareIntegration(t *testing.T) { assert.Len(t, server.binding.Security.proxyHeaders, 0) } +func TestGetCompressedFileName(t *testing.T) { + username := "test" + res := getCompressedFileName(username, []string{"single dir"}) + require.Equal(t, fmt.Sprintf("%s-single dir.zip", username), res) + res = getCompressedFileName(username, []string{"file1", "file2"}) + require.Equal(t, fmt.Sprintf("%s-download.zip", username), res) + res = getCompressedFileName(username, []string{"file1.txt"}) + require.Equal(t, fmt.Sprintf("%s-file1.zip", username), res) + // now files with full paths + res = getCompressedFileName(username, []string{"/dir/single dir"}) + require.Equal(t, fmt.Sprintf("%s-single dir.zip", username), res) + res = getCompressedFileName(username, []string{"/adir/file1", "/adir/file2"}) + require.Equal(t, fmt.Sprintf("%s-download.zip", username), res) + res = getCompressedFileName(username, []string{"/sub/dir/file1.txt"}) + require.Equal(t, fmt.Sprintf("%s-file1.zip", username), res) +} + func TestWebAdminSetupWithInstallCode(t *testing.T) { installationCode = "1234" // delete all the admins diff --git a/internal/httpd/webclient.go b/internal/httpd/webclient.go index b3447d2f..8e90a00b 100644 --- a/internal/httpd/webclient.go +++ b/internal/httpd/webclient.go @@ -653,7 +653,8 @@ func (s *httpdServer) handleWebClientDownloadZip(w http.ResponseWriter, r *http. return } - w.Header().Set("Content-Disposition", "attachment; filename=\"sftpgo-download.zip\"") + w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", + getCompressedFileName(connection.GetUsername(), filesList))) renderCompressedFiles(w, connection, name, filesList, nil) }