Skip to content

Commit b02b79f

Browse files
committed
zip creation: avoid stat if not strictly required
Signed-off-by: Nicola Murino <[email protected]>
1 parent a0f781a commit b02b79f

File tree

4 files changed

+29
-23
lines changed

4 files changed

+29
-23
lines changed

internal/common/eventmanager.go

+10-7
Original file line numberDiff line numberDiff line change
@@ -999,7 +999,7 @@ func getFileWriter(conn *BaseConnection, virtualPath string, expectedSize int64)
999999
return w, numFiles, truncatedSize, cancelFn, nil
10001000
}
10011001

1002-
func addZipEntry(wr *zipWriterWrapper, conn *BaseConnection, entryPath, baseDir string, recursion int) error {
1002+
func addZipEntry(wr *zipWriterWrapper, conn *BaseConnection, entryPath, baseDir string, info os.FileInfo, recursion int) error { //nolint:gocyclo
10031003
if entryPath == wr.Name {
10041004
// skip the archive itself
10051005
return nil
@@ -1009,10 +1009,13 @@ func addZipEntry(wr *zipWriterWrapper, conn *BaseConnection, entryPath, baseDir
10091009
return util.ErrRecursionTooDeep
10101010
}
10111011
recursion++
1012-
info, err := conn.DoStat(entryPath, 1, false)
1013-
if err != nil {
1014-
eventManagerLog(logger.LevelError, "unable to add zip entry %q, stat error: %v", entryPath, err)
1015-
return err
1012+
var err error
1013+
if info == nil {
1014+
info, err = conn.DoStat(entryPath, 1, false)
1015+
if err != nil {
1016+
eventManagerLog(logger.LevelError, "unable to add zip entry %q, stat error: %v", entryPath, err)
1017+
return err
1018+
}
10161019
}
10171020
entryName, err := getZipEntryName(entryPath, baseDir)
10181021
if err != nil {
@@ -1050,7 +1053,7 @@ func addZipEntry(wr *zipWriterWrapper, conn *BaseConnection, entryPath, baseDir
10501053
}
10511054
for _, info := range contents {
10521055
fullPath := util.CleanPath(path.Join(entryPath, info.Name()))
1053-
if err := addZipEntry(wr, conn, fullPath, baseDir, recursion); err != nil {
1056+
if err := addZipEntry(wr, conn, fullPath, baseDir, info, recursion); err != nil {
10541057
eventManagerLog(logger.LevelError, "unable to add zip entry: %v", err)
10551058
return err
10561059
}
@@ -2042,7 +2045,7 @@ func executeCompressFsActionForUser(c dataprovider.EventActionFsCompress, replac
20422045
}
20432046
startTime := time.Now()
20442047
for _, item := range paths {
2045-
if err := addZipEntry(zipWriter, conn, item, baseDir, 0); err != nil {
2048+
if err := addZipEntry(zipWriter, conn, item, baseDir, nil, 0); err != nil {
20462049
closeWriterAndUpdateQuota(writer, conn, name, "", numFiles, truncatedSize, err, operationUpload, startTime) //nolint:errcheck
20472050
return err
20482051
}

internal/common/eventmanager_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1823,7 +1823,7 @@ func TestFilesystemActionErrors(t *testing.T) {
18231823
Writer: zip.NewWriter(bytes.NewBuffer(nil)),
18241824
Entries: map[string]bool{},
18251825
}
1826-
err = addZipEntry(wr, conn, "/adir/sub/f.dat", "/adir/sub/sub", 0)
1826+
err = addZipEntry(wr, conn, "/adir/sub/f.dat", "/adir/sub/sub", nil, 0)
18271827
assert.Error(t, err)
18281828
assert.Contains(t, getErrorString(err), "is outside base dir")
18291829
}
@@ -1833,7 +1833,7 @@ func TestFilesystemActionErrors(t *testing.T) {
18331833
Writer: zip.NewWriter(bytes.NewBuffer(nil)),
18341834
Entries: map[string]bool{},
18351835
}
1836-
err = addZipEntry(wr, conn, "/p1", "/", 2000)
1836+
err = addZipEntry(wr, conn, "/p1", "/", nil, 2000)
18371837
assert.ErrorIs(t, err, util.ErrRecursionTooDeep)
18381838

18391839
err = dataprovider.DeleteUser(username, "", "", "")

internal/httpd/api_utils.go

+10-7
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ func renderCompressedFiles(w http.ResponseWriter, conn *Connection, baseDir stri
384384

385385
for _, file := range files {
386386
fullPath := util.CleanPath(path.Join(baseDir, file))
387-
if err := addZipEntry(wr, conn, fullPath, baseDir, 0); err != nil {
387+
if err := addZipEntry(wr, conn, fullPath, baseDir, nil, 0); err != nil {
388388
if share != nil {
389389
dataprovider.UpdateShareLastUse(share, -1) //nolint:errcheck
390390
}
@@ -400,16 +400,19 @@ func renderCompressedFiles(w http.ResponseWriter, conn *Connection, baseDir stri
400400
}
401401
}
402402

403-
func addZipEntry(wr *zip.Writer, conn *Connection, entryPath, baseDir string, recursion int) error {
403+
func addZipEntry(wr *zip.Writer, conn *Connection, entryPath, baseDir string, info os.FileInfo, recursion int) error {
404404
if recursion >= util.MaxRecursion {
405405
conn.Log(logger.LevelDebug, "unable to add zip entry %q, recursion too depth: %d", entryPath, recursion)
406406
return util.ErrRecursionTooDeep
407407
}
408408
recursion++
409-
info, err := conn.Stat(entryPath, 1)
410-
if err != nil {
411-
conn.Log(logger.LevelDebug, "unable to add zip entry %q, stat error: %v", entryPath, err)
412-
return err
409+
var err error
410+
if info == nil {
411+
info, err = conn.Stat(entryPath, 1)
412+
if err != nil {
413+
conn.Log(logger.LevelDebug, "unable to add zip entry %q, stat error: %v", entryPath, err)
414+
return err
415+
}
413416
}
414417
entryName, err := getZipEntryName(entryPath, baseDir)
415418
if err != nil {
@@ -441,7 +444,7 @@ func addZipEntry(wr *zip.Writer, conn *Connection, entryPath, baseDir string, re
441444
}
442445
for _, info := range contents {
443446
fullPath := util.CleanPath(path.Join(entryPath, info.Name()))
444-
if err := addZipEntry(wr, conn, fullPath, baseDir, recursion); err != nil {
447+
if err := addZipEntry(wr, conn, fullPath, baseDir, info, recursion); err != nil {
445448
return err
446449
}
447450
}

internal/httpd/internal_test.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -2291,14 +2291,14 @@ func TestZipErrors(t *testing.T) {
22912291
assert.Contains(t, err.Error(), "write error")
22922292
}
22932293

2294-
err = addZipEntry(wr, connection, "/"+filepath.Base(testDir), "/", 0)
2294+
err = addZipEntry(wr, connection, "/"+filepath.Base(testDir), "/", nil, 0)
22952295
if assert.Error(t, err) {
22962296
assert.Contains(t, err.Error(), "write error")
22972297
}
2298-
err = addZipEntry(wr, connection, "/"+filepath.Base(testDir), "/", 2000)
2298+
err = addZipEntry(wr, connection, "/"+filepath.Base(testDir), "/", nil, 2000)
22992299
assert.ErrorIs(t, err, util.ErrRecursionTooDeep)
23002300

2301-
err = addZipEntry(wr, connection, "/"+filepath.Base(testDir), path.Join("/", filepath.Base(testDir), "dir"), 0)
2301+
err = addZipEntry(wr, connection, "/"+filepath.Base(testDir), path.Join("/", filepath.Base(testDir), "dir"), nil, 0)
23022302
if assert.Error(t, err) {
23032303
assert.Contains(t, err.Error(), "is outside base dir")
23042304
}
@@ -2307,14 +2307,14 @@ func TestZipErrors(t *testing.T) {
23072307
err = os.WriteFile(testFilePath, util.GenerateRandomBytes(65535), os.ModePerm)
23082308
assert.NoError(t, err)
23092309
err = addZipEntry(wr, connection, path.Join("/", filepath.Base(testDir), filepath.Base(testFilePath)),
2310-
"/"+filepath.Base(testDir), 0)
2310+
"/"+filepath.Base(testDir), nil, 0)
23112311
if assert.Error(t, err) {
23122312
assert.Contains(t, err.Error(), "write error")
23132313
}
23142314

23152315
connection.User.Permissions["/"] = []string{dataprovider.PermListItems}
23162316
err = addZipEntry(wr, connection, path.Join("/", filepath.Base(testDir), filepath.Base(testFilePath)),
2317-
"/"+filepath.Base(testDir), 0)
2317+
"/"+filepath.Base(testDir), nil, 0)
23182318
assert.ErrorIs(t, err, os.ErrPermission)
23192319

23202320
// creating a virtual folder to a missing path stat is ok but readdir fails
@@ -2326,14 +2326,14 @@ func TestZipErrors(t *testing.T) {
23262326
})
23272327
connection.User = user
23282328
wr = zip.NewWriter(bytes.NewBuffer(make([]byte, 0)))
2329-
err = addZipEntry(wr, connection, user.VirtualFolders[0].VirtualPath, "/", 0)
2329+
err = addZipEntry(wr, connection, user.VirtualFolders[0].VirtualPath, "/", nil, 0)
23302330
assert.Error(t, err)
23312331

23322332
user.Filters.FilePatterns = append(user.Filters.FilePatterns, sdk.PatternsFilter{
23332333
Path: "/",
23342334
DeniedPatterns: []string{"*.zip"},
23352335
})
2336-
err = addZipEntry(wr, connection, "/"+filepath.Base(testDir), "/", 0)
2336+
err = addZipEntry(wr, connection, "/"+filepath.Base(testDir), "/", nil, 0)
23372337
assert.ErrorIs(t, err, os.ErrPermission)
23382338

23392339
err = os.RemoveAll(testDir)

0 commit comments

Comments
 (0)