mirror of
				https://github.com/cloudreve/cloudreve.git
				synced 2025-10-31 08:39:10 +08:00 
			
		
		
		
	Feat: use goroutine to detect upload-canceling action / Object name validate
This commit is contained in:
		| @ -7,4 +7,5 @@ var ( | ||||
| 	FileSizeTooBigError          = errors.New("单个文件尺寸太大") | ||||
| 	FileExtensionNotAllowedError = errors.New("不允许上传此类型的文件") | ||||
| 	InsufficientCapacityError    = errors.New("容量空间不足") | ||||
| 	IlegalObjectNameError        = errors.New("目标名称非法") | ||||
| ) | ||||
|  | ||||
| @ -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("取消上传") | ||||
| 		// 归还空间 | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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 | ||||
| } | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 HFO4
					HFO4