优化
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
@@ -17,7 +18,7 @@ import (
|
||||
)
|
||||
|
||||
func (uc *MediaUsecase) chunkPrefix(uploadID uint) string {
|
||||
directory := ".chunks"
|
||||
directory := "uploads/chunks"
|
||||
if uc.settings != nil {
|
||||
if configured := strings.Trim(uc.settings.MediaSettings().ChunkDir, "/\\ "); configured != "" {
|
||||
directory = configured
|
||||
@@ -34,9 +35,6 @@ func (uc *MediaUsecase) InitUpload(ctx context.Context, userID uint, name, hash
|
||||
if err := validateMediaName(name); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
if size <= 0 || chunkSize <= 0 || total <= 0 {
|
||||
return nil, nil, nil, errors.New("上传参数不合法")
|
||||
}
|
||||
if completed, err := uc.FindCompletedSession(ctx, userID, hash); err == nil && completed.MediaID != 0 {
|
||||
if media, findErr := uc.FindMedia(ctx, completed.MediaID); findErr == nil {
|
||||
copy := &MediaFile{Name: name, URL: media.URL, Tag: media.Tag, Key: media.Key}
|
||||
@@ -65,29 +63,50 @@ func (uc *MediaUsecase) InitUpload(ctx context.Context, userID uint, name, hash
|
||||
}
|
||||
func (uc *MediaUsecase) SaveChunk(ctx context.Context, userID, uploadID uint, index int, expected string, reader io.Reader) error {
|
||||
session, err := uc.FindUploadSession(ctx, uploadID)
|
||||
if err != nil || session.UserID != userID {
|
||||
return errors.New("上传会话不存在或无权操作")
|
||||
if err != nil {
|
||||
return errors.New("上传会话不存在")
|
||||
}
|
||||
if session.UserID != userID {
|
||||
return errors.New("无权操作该上传")
|
||||
}
|
||||
if session.Status != "uploading" {
|
||||
return errors.New("上传会话状态不允许收片")
|
||||
}
|
||||
hash := md5.New()
|
||||
key := uc.chunkKey(uploadID, index)
|
||||
stored, err := uc.files.Put(ctx, key, io.TeeReader(reader, hash))
|
||||
temporary, err := os.CreateTemp("", "kra-upload-chunk-*")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
temporaryName := temporary.Name()
|
||||
defer os.Remove(temporaryName)
|
||||
defer temporary.Close()
|
||||
if _, err = io.Copy(io.MultiWriter(temporary, hash), reader); err != nil {
|
||||
return err
|
||||
}
|
||||
actual := hex.EncodeToString(hash.Sum(nil))
|
||||
if actual != expected {
|
||||
_ = uc.files.Delete(ctx, key)
|
||||
return fmt.Errorf("分片 %d 校验失败", index)
|
||||
}
|
||||
if _, err = temporary.Seek(0, io.SeekStart); err != nil {
|
||||
return err
|
||||
}
|
||||
stored, err := uc.files.Put(ctx, key, temporary)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return uc.UpsertChunk(ctx, uploadID, &UploadChunk{Index: index, Hash: actual, Size: stored.Size})
|
||||
}
|
||||
func (uc *MediaUsecase) CompleteUpload(ctx context.Context, userID, uploadID uint, mime string) (*MediaFile, error) {
|
||||
session, err := uc.FindUploadSession(ctx, uploadID)
|
||||
if err != nil || session.UserID != userID {
|
||||
return nil, errors.New("上传会话不存在或无权操作")
|
||||
if err != nil {
|
||||
return nil, errors.New("上传会话不存在")
|
||||
}
|
||||
if session.UserID != userID {
|
||||
return nil, errors.New("无权操作该上传")
|
||||
}
|
||||
if err = validateMediaName(session.FileName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
claimed, err := uc.ClaimUploadSession(ctx, uploadID)
|
||||
if err != nil {
|
||||
@@ -122,7 +141,10 @@ func (uc *MediaUsecase) CompleteUpload(ctx context.Context, userID, uploadID uin
|
||||
_ = uc.files.Delete(ctx, key)
|
||||
return fail(errors.New("整文件校验失败"))
|
||||
}
|
||||
media := &MediaFile{Name: session.FileName, URL: stored.URL, Tag: strings.TrimPrefix(ext, "."), Key: key, Size: stored.Size, Mime: mime, MD5: hash, UserID: userID}
|
||||
// Keep the size declared when the upload session was created. The full-file
|
||||
// MD5 above remains the integrity check even if storage reports another
|
||||
// byte count.
|
||||
media := &MediaFile{Name: session.FileName, URL: stored.URL, Tag: strings.TrimPrefix(filepath.Ext(session.FileName), "."), Key: key, Size: session.FileSize, Mime: mime, MD5: hash, UserID: userID}
|
||||
if err = uc.CreateMedia(ctx, media); err != nil {
|
||||
_ = uc.files.Delete(ctx, key)
|
||||
return fail(err)
|
||||
@@ -134,8 +156,11 @@ func (uc *MediaUsecase) CompleteUpload(ctx context.Context, userID, uploadID uin
|
||||
}
|
||||
func (uc *MediaUsecase) CancelUpload(ctx context.Context, userID, uploadID uint) error {
|
||||
session, err := uc.FindUploadSession(ctx, uploadID)
|
||||
if err != nil || session.UserID != userID {
|
||||
return errors.New("上传会话不存在或无权操作")
|
||||
if err != nil {
|
||||
return errors.New("上传会话不存在")
|
||||
}
|
||||
if session.UserID != userID {
|
||||
return errors.New("无权操作该上传")
|
||||
}
|
||||
_ = uc.DeleteChunks(ctx, uploadID)
|
||||
_ = uc.files.DeletePrefix(ctx, uc.chunkPrefix(uploadID))
|
||||
|
||||
Reference in New Issue
Block a user