Skip to content

Commit 192b698

Browse files
committed
calculate file checksum when updating file using wopi or text/code editor or webdav upload
1 parent a26893a commit 192b698

File tree

4 files changed

+55
-13
lines changed

4 files changed

+55
-13
lines changed

pkg/filesystem/fsctx/stream.go

+24
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package fsctx
22

33
import (
4+
"encoding/hex"
45
"errors"
56
"github.com/HFO4/aliyun-oss-go-sdk/oss"
7+
"hash"
68
"io"
9+
"strings"
710
"time"
811
)
912

@@ -121,3 +124,24 @@ func (file *FileStream) SetSize(size uint64) {
121124
func (file *FileStream) SetModel(fileModel interface{}) {
122125
file.Model = fileModel
123126
}
127+
128+
type ChecksumFileStream struct {
129+
Md5 hash.Hash
130+
Sha1 hash.Hash
131+
io.Reader
132+
io.Closer
133+
}
134+
135+
func (file *ChecksumFileStream) Hash() string {
136+
var sb strings.Builder
137+
138+
sb.WriteString("MD5:")
139+
sb.WriteString(hex.EncodeToString(file.Md5.Sum(nil)))
140+
141+
sb.WriteByte(' ')
142+
143+
sb.WriteString("SHA1:")
144+
sb.WriteString(hex.EncodeToString(file.Sha1.Sum(nil)))
145+
146+
return sb.String()
147+
}

pkg/filesystem/hooks.go

+20-11
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@ package filesystem
22

33
import (
44
"context"
5+
"crypto/md5"
6+
"crypto/sha1"
57
model "github.com/cloudreve/Cloudreve/v3/models"
68
"github.com/cloudreve/Cloudreve/v3/pkg/cache"
79
"github.com/cloudreve/Cloudreve/v3/pkg/cluster"
810
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/driver/local"
911
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/fsctx"
1012
"github.com/cloudreve/Cloudreve/v3/pkg/serializer"
1113
"github.com/cloudreve/Cloudreve/v3/pkg/util"
14+
"io"
1215
"io/ioutil"
1316
"net/http"
1417
"strconv"
@@ -282,23 +285,29 @@ func NewWebdavAfterUploadHook(request *http.Request) func(ctx context.Context, f
282285
modtime = time.Unix(timeUnix, 0)
283286
}
284287
}
285-
checksum := request.Header.Get("OC-Checksum")
286288

287289
return func(ctx context.Context, fs *FileSystem, newFile fsctx.FileHeader) error {
288290
file := newFile.Info().Model.(*model.File)
289291
if !modtime.IsZero() {
290-
err := model.DB.Model(file).UpdateColumn("updated_at", modtime).Error
291-
if err != nil {
292-
return err
293-
}
294-
}
295-
296-
if checksum != "" {
297-
return file.UpdateMetadata(map[string]string{
298-
model.ChecksumMetadataKey: checksum,
299-
})
292+
return model.DB.Model(file).UpdateColumn("updated_at", modtime).Error
300293
}
301294

302295
return nil
303296
}
304297
}
298+
299+
// NewChecksumFileStreamAndAfterUploadHook 创建一个计算hash的数据流和相应的钩子函数
300+
func NewChecksumFileStreamAndAfterUploadHook(rc io.ReadCloser) (io.ReadCloser, Hook) {
301+
cfs := &fsctx.ChecksumFileStream{
302+
Md5: md5.New(),
303+
Sha1: sha1.New(),
304+
Closer: rc,
305+
}
306+
cfs.Reader = io.TeeReader(rc, io.MultiWriter(cfs.Md5, cfs.Sha1))
307+
return cfs, func(ctx context.Context, fs *FileSystem, newFile fsctx.FileHeader) error {
308+
file := newFile.Info().Model.(*model.File)
309+
return file.UpdateMetadata(map[string]string{
310+
model.ChecksumMetadataKey: cfs.Hash(),
311+
})
312+
}
313+
}

pkg/webdav/webdav.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,13 @@ func (h *Handler) handlePut(w http.ResponseWriter, r *http.Request, fs *filesyst
344344
}
345345
fileName := path.Base(reqPath)
346346
filePath := path.Dir(reqPath)
347+
348+
// 计算hash
349+
file, hook := filesystem.NewChecksumFileStreamAndAfterUploadHook(r.Body)
350+
347351
fileData := fsctx.FileStream{
348352
MimeType: r.Header.Get("Content-Type"),
349-
File: r.Body,
353+
File: file,
350354
Size: fileSize,
351355
Name: fileName,
352356
VirtualPath: filePath,
@@ -391,6 +395,7 @@ func (h *Handler) handlePut(w http.ResponseWriter, r *http.Request, fs *filesyst
391395

392396
// rclone 请求
393397
fs.Use("AfterUpload", filesystem.NewWebdavAfterUploadHook(r))
398+
fs.Use("AfterUpload", hook)
394399

395400
// 执行上传
396401
err = fs.Upload(ctx, &fileData)

service/explorer/file.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -411,9 +411,12 @@ func (service *FileIDService) PutContent(ctx context.Context, c *gin.Context) se
411411
return serializer.ParamErr("Invalid content-length value", err)
412412
}
413413

414+
// 计算hash
415+
file, hook := filesystem.NewChecksumFileStreamAndAfterUploadHook(c.Request.Body)
416+
414417
fileData := fsctx.FileStream{
415418
MimeType: c.Request.Header.Get("Content-Type"),
416-
File: c.Request.Body,
419+
File: file,
417420
Size: fileSize,
418421
Mode: fsctx.Overwrite,
419422
}
@@ -453,6 +456,7 @@ func (service *FileIDService) PutContent(ctx context.Context, c *gin.Context) se
453456
fs.Use("BeforeUpload", filesystem.HookValidateFile)
454457
fs.Use("BeforeUpload", filesystem.HookValidateCapacityDiff)
455458
fs.Use("AfterUpload", filesystem.GenericAfterUpdate)
459+
fs.Use("AfterUpload", hook)
456460

457461
// 执行上传
458462
uploadCtx = context.WithValue(uploadCtx, fsctx.FileModelCtx, originFile[0])

0 commit comments

Comments
 (0)