Feat: use goroutine to detect upload-canceling action / Object name validate

This commit is contained in:
HFO4
2019-11-18 13:26:32 +08:00
parent 331931e539
commit 160f964564
6 changed files with 54 additions and 1 deletions

View File

@ -7,4 +7,5 @@ var (
FileSizeTooBigError = errors.New("单个文件尺寸太大")
FileExtensionNotAllowedError = errors.New("不允许上传此类型的文件")
InsufficientCapacityError = errors.New("容量空间不足")
IlegalObjectNameError = errors.New("目标名称非法")
)

View File

@ -2,8 +2,10 @@ package filesystem
import (
"context"
"fmt"
"github.com/HFO4/cloudreve/models"
"github.com/HFO4/cloudreve/pkg/filesystem/local"
"github.com/gin-gonic/gin"
"io"
"path/filepath"
)
@ -64,6 +66,10 @@ func NewFileSystem(user *model.User) (*FileSystem, error) {
}, nil
}
/*
上传处理相关
*/
// Upload 上传文件
func (fs *FileSystem) Upload(ctx context.Context, file FileData) (err error) {
// 上传前的钩子
@ -75,6 +81,9 @@ func (fs *FileSystem) Upload(ctx context.Context, file FileData) (err error) {
// 生成文件名和路径
savePath := fs.GenerateSavePath(file)
// 处理客户端未完成上传时,关闭连接
go fs.CancelUpload(ctx, savePath, file)
// 保存文件
err = fs.Handler.Put(ctx, file, savePath)
if err != nil {
@ -91,3 +100,16 @@ func (fs *FileSystem) GenerateSavePath(file FileData) string {
fs.User.Policy.GenerateFileName(fs.User.Model.ID, file.GetFileName()),
)
}
// CancelUpload 监测客户端取消上传
func (fs *FileSystem) CancelUpload(ctx context.Context, path string, file FileData) {
ginCtx := ctx.Value("ginCtx").(*gin.Context)
select {
case <-ctx.Done():
// 客户端正常关闭,不执行操作
case <-ginCtx.Request.Context().Done():
// 客户端取消了上传,删除保存的文件
fmt.Println("取消上传")
// 归还空间
}
}

View File

@ -11,6 +11,11 @@ func GenericBeforeUpload(ctx context.Context, fs *FileSystem, file FileData) err
return FileSizeTooBigError
}
// 验证文件名
if !fs.ValidateLegalName(ctx, file.GetFileName()) {
return IlegalObjectNameError
}
// 验证扩展名
if !fs.ValidateExtension(ctx, file.GetFileName()) {
return FileExtensionNotAllowedError

View File

@ -24,12 +24,14 @@ func (handler Handler) Put(ctx context.Context, file io.ReadCloser, dst string)
}
}
// 创建目标文件
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
// 写入文件内容
_, err = io.Copy(out, file)
return err
}

View File

@ -7,6 +7,19 @@ import (
"strings"
)
// 文件/路径名保留字符
var reservedCharacter = []string{"\\", "?", "*", "<", "\"", ":", ">", "/"}
// ValidateLegalName 验证文件名/文件夹名是否合法
func (fs *FileSystem) ValidateLegalName(ctx context.Context, name string) bool {
for _, value := range reservedCharacter {
if strings.Contains(name, value) {
return false
}
}
return true
}
// ValidateFileSize 验证上传的文件大小是否超出限制
func (fs *FileSystem) ValidateFileSize(ctx context.Context, size uint64) bool {
return size <= fs.User.Policy.MaxSize