From 406f908d9e570728bf17def39048eaf54e9babab Mon Sep 17 00:00:00 2001 From: hexxa Date: Sat, 5 Mar 2022 16:55:01 +0800 Subject: [PATCH] fix(files): incorrect delete folder operation order --- src/db/boltstore/bolt_store.go | 50 +++++++++-------- src/handlers/fileshdr/handlers.go | 74 +++++++++++++------------ src/server/server_files_test.go | 9 +++ src/server/testdata/test_quickshare.db | Bin 524288 -> 524288 bytes 4 files changed, 75 insertions(+), 58 deletions(-) diff --git a/src/db/boltstore/bolt_store.go b/src/db/boltstore/bolt_store.go index 04ee781..42339e6 100644 --- a/src/db/boltstore/bolt_store.go +++ b/src/db/boltstore/bolt_store.go @@ -286,7 +286,7 @@ func (bs *BoltStore) delShareID(tx *bolt.Tx, itemPath string) error { return nil } -func (bs *BoltStore) DelInfos(userID uint64, itemPath string) error { +func (bs *BoltStore) DelInfos(userID uint64, itemPath string, isDir bool) error { return bs.boltdb.Update(func(tx *bolt.Tx) error { var err error @@ -297,35 +297,37 @@ func (bs *BoltStore) DelInfos(userID uint64, itemPath string) error { } fileInfoBytes := fileInfoBucket.Get([]byte(itemPath)) - if fileInfoBucket == nil { - return db.ErrKeyNotFound - } + if fileInfoBytes == nil { + if !isDir { + return db.ErrKeyNotFound + } + } else { + fileInfo := &db.FileInfo{} + err = json.Unmarshal(fileInfoBytes, fileInfo) + if err != nil { + return err + } - fileInfo := &db.FileInfo{} - err = json.Unmarshal(fileInfoBytes, fileInfo) - if err != nil { - return err - } + err = fileInfoBucket.Delete([]byte(itemPath)) + if err != nil { + return err + } - err = fileInfoBucket.Delete([]byte(itemPath)) - if err != nil { - return err - } + // decr used space + userInfo, err := bs.getUserInfo(tx, userID) + if err != nil { + return err + } - // decr used space - userInfo, err := bs.getUserInfo(tx, userID) - if err != nil { - return err - } - - userInfo.UsedSpace -= fileInfo.Size - err = bs.setUserInfo(tx, userID, userInfo) - if err != nil { - return err + userInfo.UsedSpace -= fileInfo.Size + err = bs.setUserInfo(tx, userID, userInfo) + if err != nil { + return err + } } // delete share id - if fileInfo.IsDir { + if isDir { err = bs.delShareID(tx, itemPath) if err != nil { return err diff --git a/src/handlers/fileshdr/handlers.go b/src/handlers/fileshdr/handlers.go index f16c04f..ee664aa 100644 --- a/src/handlers/fileshdr/handlers.go +++ b/src/handlers/fileshdr/handlers.go @@ -261,36 +261,30 @@ func (h *FileHandlers) Delete(c *gin.Context) { return } + var txErr error locker := h.NewAutoLocker(c, lockName(filePath)) locker.Exec(func() { + info, err := h.deps.FS().Stat(filePath) + if err != nil { + txErr = err + return + } + err = h.deps.FS().Remove(filePath) if err != nil { - c.JSON(q.ErrResp(c, 500, err)) + txErr = err + return + } + + err = h.deps.BoltStore().DelInfos(userIDInt, filePath, info.IsDir()) + if err != nil { + txErr = err return } }) - // info, err := h.deps.FileInfos().GetInfo(filePath) - // if err != nil { - // c.JSON(q.ErrResp(c, 500, err)) - // return - // } - - // err = h.deps.Users().SetUsed(userIDInt, false, info.Size) - // if err != nil { - // c.JSON(q.ErrResp(c, 500, err)) - // return - // } - - // err = h.deps.FileInfos().DelInfo(filePath) - // if err != nil { - // c.JSON(q.ErrResp(c, 500, err)) - // return - // } - - err = h.deps.BoltStore().DelInfos(userIDInt, filePath) - if err != nil { - c.JSON(q.ErrResp(c, 500, err)) + if txErr != nil { + c.JSON(q.ErrResp(c, 500, txErr)) return } c.JSON(q.Resp(200)) @@ -450,6 +444,8 @@ func (h *FileHandlers) UploadChunk(c *gin.Context) { return } + var txErr error + var statusCode int tmpFilePath := q.UploadPath(userName, req.Path) locker := h.NewAutoLocker(c, lockName(tmpFilePath)) locker.Exec(func() { @@ -457,28 +453,28 @@ func (h *FileHandlers) UploadChunk(c *gin.Context) { _, fileSize, uploaded, err := h.deps.FileInfos().GetUploadInfo(userID, tmpFilePath) if err != nil { - c.JSON(q.ErrResp(c, 500, err)) + txErr, statusCode = err, 500 return } else if uploaded != req.Offset { - c.JSON(q.ErrResp(c, 500, errors.New("offset != uploaded"))) + txErr, statusCode = errors.New("offset != uploaded"), 500 return } content, err := base64.StdEncoding.DecodeString(req.Content) if err != nil { - c.JSON(q.ErrResp(c, 500, err)) + txErr, statusCode = err, 500 return } wrote, err := h.deps.FS().WriteAt(tmpFilePath, []byte(content), req.Offset) if err != nil { - c.JSON(q.ErrResp(c, 500, err)) + txErr, statusCode = err, 500 return } err = h.deps.FileInfos().SetUploadInfo(userID, tmpFilePath, req.Offset+int64(wrote)) if err != nil { - c.JSON(q.ErrResp(c, 500, err)) + txErr, statusCode = err, 500 return } @@ -486,19 +482,19 @@ func (h *FileHandlers) UploadChunk(c *gin.Context) { if uploaded+int64(wrote) == fileSize { fsFilePath, err := h.getFSFilePath(userID, req.Path) if err != nil { - c.JSON(q.ErrResp(c, 500, err)) + txErr, statusCode = err, 500 return } err = h.deps.BoltStore().MoveUploadingInfos(userIDInt, tmpFilePath, fsFilePath) if err != nil { - c.JSON(q.ErrResp(c, 500, err)) + txErr, statusCode = err, 500 return } err = h.deps.FS().Rename(tmpFilePath, fsFilePath) if err != nil { - c.JSON(q.ErrResp(c, 500, fmt.Errorf("%s error: %w", req.Path, err))) + txErr, statusCode = fmt.Errorf("%s error: %w", req.Path, err), 500 return } @@ -506,7 +502,7 @@ func (h *FileHandlers) UploadChunk(c *gin.Context) { FilePath: fsFilePath, }) if err != nil { - c.JSON(q.ErrResp(c, 500, err)) + txErr, statusCode = err, 500 return } @@ -518,11 +514,15 @@ func (h *FileHandlers) UploadChunk(c *gin.Context) { ), ) if err != nil { - c.JSON(q.ErrResp(c, 500, err)) + txErr, statusCode = err, 500 return } } + if txErr != nil { + c.JSON(q.ErrResp(c, statusCode, txErr)) + return + } c.JSON(200, &UploadStatusResp{ Path: req.Path, IsDir: false, @@ -874,6 +874,8 @@ func (h *FileHandlers) DelUploading(c *gin.Context) { return } + var txErr error + var statusCode int tmpFilePath := q.UploadPath(userName, filePath) locker := h.NewAutoLocker(c, lockName(tmpFilePath)) locker.Exec(func() { @@ -882,17 +884,21 @@ func (h *FileHandlers) DelUploading(c *gin.Context) { if os.IsNotExist(err) { // no op } else { - c.JSON(q.ErrResp(c, 500, err)) + txErr, statusCode = err, 500 return } } else { err = h.deps.FS().Remove(tmpFilePath) if err != nil { - c.JSON(q.ErrResp(c, 500, err)) + txErr, statusCode = err, 500 return } } }) + if txErr != nil { + c.JSON(q.ErrResp(c, statusCode, txErr)) + return + } err = h.deps.BoltStore().DelUploadingInfos(userIDInt, tmpFilePath) if err != nil { diff --git a/src/server/server_files_test.go b/src/server/server_files_test.go index 4ba70c3..8a3656b 100644 --- a/src/server/server_files_test.go +++ b/src/server/server_files_test.go @@ -377,6 +377,15 @@ func TestFileHandlers(t *testing.T) { t.Fatalf("size not match %d %d \n", len(content), metadata.Size) } } + + for _, dirPath := range []string{srcDir, dstDir} { + res, _, errs := cl.Delete(dirPath) + if len(errs) > 0 { + t.Fatal(errs) + } else if res.StatusCode != 200 { + t.Fatal(res.StatusCode) + } + } }) t.Run("test download APIs: Download(normal, ranges)", func(t *testing.T) { diff --git a/src/server/testdata/test_quickshare.db b/src/server/testdata/test_quickshare.db index 79fb228f430434b3a7ad925fa2af56de424549cb..20304f1a3e269f01b8af9730b154d2b4981de0e7 100644 GIT binary patch delta 81 zcmZo@P-tjSnBX9=g@KU)1URjAuIi@9g>E+tVBEkzNx(s1D^#Y?R%iyB*VJl=Op`*J Z0%My3Q=0;Fn*vLl0&ANB+cE|A2LMQa6t@5X delta 81 zcmZo@P-tjSnBX9=h=Gv-1onqsPQN@iNPfFv0OJP!NdgW6i=i^=5j(ZkG@o>Z$TTUm aDKNGvFtsT#w<)l+DX_LFuq{(ye*gf~+81B|