mirror of
https://github.com/halejohn/Cloudreve.git
synced 2026-01-26 09:34:57 +08:00
Refactor: create placeholder file and record upload session id in it
This commit is contained in:
@@ -185,7 +185,7 @@ func (handler Driver) Get(ctx context.Context, path string) (response.RSCloser,
|
||||
// Put 将文件流保存到指定目录
|
||||
func (handler Driver) Put(ctx context.Context, file fsctx.FileHeader) error {
|
||||
opt := &cossdk.ObjectPutOptions{}
|
||||
_, err := handler.Client.Object.Put(ctx, file.GetSavePath(), file, opt)
|
||||
_, err := handler.Client.Object.Put(ctx, file.Info().SavePath, file, opt)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -331,6 +331,7 @@ func (handler Driver) Token(ctx context.Context, ttl int64, uploadSession *seria
|
||||
apiURL := siteURL.ResolveReference(apiBaseURI).String()
|
||||
|
||||
// 上传策略
|
||||
savePath := file.Info().SavePath
|
||||
startTime := time.Now()
|
||||
endTime := startTime.Add(time.Duration(ttl) * time.Second)
|
||||
keyTime := fmt.Sprintf("%d;%d", startTime.Unix(), endTime.Unix())
|
||||
@@ -338,7 +339,7 @@ func (handler Driver) Token(ctx context.Context, ttl int64, uploadSession *seria
|
||||
Expiration: endTime.UTC().Format(time.RFC3339),
|
||||
Conditions: []interface{}{
|
||||
map[string]string{"bucket": handler.Policy.BucketName},
|
||||
map[string]string{"$key": file.GetSavePath()},
|
||||
map[string]string{"$key": savePath},
|
||||
map[string]string{"x-cos-meta-callback": apiURL},
|
||||
map[string]string{"x-cos-meta-key": uploadSession.Key},
|
||||
map[string]string{"q-sign-algorithm": "sha1"},
|
||||
@@ -352,7 +353,7 @@ func (handler Driver) Token(ctx context.Context, ttl int64, uploadSession *seria
|
||||
[]interface{}{"content-length-range", 0, handler.Policy.MaxSize})
|
||||
}
|
||||
|
||||
res, err := handler.getUploadCredential(ctx, postPolicy, keyTime, file.GetSavePath())
|
||||
res, err := handler.getUploadCredential(ctx, postPolicy, keyTime, savePath)
|
||||
if err == nil {
|
||||
res.Callback = apiURL
|
||||
res.Key = uploadSession.Key
|
||||
|
||||
@@ -85,10 +85,11 @@ func (handler Driver) Get(ctx context.Context, path string) (response.RSCloser,
|
||||
// Put 将文件流保存到指定目录
|
||||
func (handler Driver) Put(ctx context.Context, file fsctx.FileHeader) error {
|
||||
defer file.Close()
|
||||
dst := util.RelativePath(filepath.FromSlash(file.GetSavePath()))
|
||||
fileInfo := file.Info()
|
||||
dst := util.RelativePath(filepath.FromSlash(fileInfo.SavePath))
|
||||
|
||||
// 如果非 Overwrite,则检查是否有重名冲突
|
||||
if file.GetMode() == fsctx.Create {
|
||||
if fileInfo.Mode == fsctx.Create {
|
||||
if util.Exists(dst) {
|
||||
util.Log().Warning("物理同名文件已存在或不可用: %s", dst)
|
||||
return errors.New("物理同名文件已存在或不可用")
|
||||
|
||||
@@ -258,14 +258,15 @@ func (client *Client) UploadChunk(ctx context.Context, uploadURL string, chunk *
|
||||
|
||||
// Upload 上传文件
|
||||
func (client *Client) Upload(ctx context.Context, file fsctx.FileHeader) error {
|
||||
fileInfo := file.Info()
|
||||
// 决定是否覆盖文件
|
||||
overwrite := "replace"
|
||||
if file.GetMode() != fsctx.Create {
|
||||
if fileInfo.Mode != fsctx.Create {
|
||||
overwrite = "fail"
|
||||
}
|
||||
|
||||
size := int(file.GetSize())
|
||||
dst := file.GetSavePath()
|
||||
size := int(fileInfo.Size)
|
||||
dst := fileInfo.SavePath
|
||||
|
||||
// 小文件,使用简单上传接口上传
|
||||
if size <= int(SmallFileSize) {
|
||||
|
||||
@@ -223,9 +223,10 @@ func (handler Driver) replaceSourceHost(origin string) (string, error) {
|
||||
|
||||
// Token 获取上传会话URL
|
||||
func (handler Driver) Token(ctx context.Context, ttl int64, uploadSession *serializer.UploadSession, file fsctx.FileHeader) (serializer.UploadCredential, error) {
|
||||
fileInfo := file.Info()
|
||||
|
||||
// 如果小于4MB,则由服务端中转
|
||||
if file.GetSize() <= SmallFileSize {
|
||||
if fileInfo.Size <= SmallFileSize {
|
||||
return serializer.UploadCredential{}, nil
|
||||
}
|
||||
|
||||
@@ -234,13 +235,13 @@ func (handler Driver) Token(ctx context.Context, ttl int64, uploadSession *seria
|
||||
apiBaseURI, _ := url.Parse("/api/v3/callback/onedrive/finish/" + uploadSession.Key)
|
||||
apiURL := siteURL.ResolveReference(apiBaseURI)
|
||||
|
||||
uploadURL, err := handler.Client.CreateUploadSession(ctx, file.GetSavePath(), WithConflictBehavior("fail"))
|
||||
uploadURL, err := handler.Client.CreateUploadSession(ctx, fileInfo.SavePath, WithConflictBehavior("fail"))
|
||||
if err != nil {
|
||||
return serializer.UploadCredential{}, err
|
||||
}
|
||||
|
||||
// 监控回调及上传
|
||||
go handler.Client.MonitorUpload(uploadURL, uploadSession.Key, file.GetSavePath(), file.GetSize(), ttl)
|
||||
go handler.Client.MonitorUpload(uploadURL, uploadSession.Key, fileInfo.SavePath, fileInfo.Size, ttl)
|
||||
|
||||
return serializer.UploadCredential{
|
||||
Policy: uploadURL,
|
||||
|
||||
@@ -226,6 +226,7 @@ func (handler Driver) Get(ctx context.Context, path string) (response.RSCloser,
|
||||
// Put 将文件流保存到指定目录
|
||||
func (handler Driver) Put(ctx context.Context, file fsctx.FileHeader) error {
|
||||
defer file.Close()
|
||||
fileInfo := file.Info()
|
||||
|
||||
// 初始化客户端
|
||||
if err := handler.InitOSSClient(false); err != nil {
|
||||
@@ -237,7 +238,7 @@ func (handler Driver) Put(ctx context.Context, file fsctx.FileHeader) error {
|
||||
|
||||
// 是否允许覆盖
|
||||
overwrite := true
|
||||
if file.GetMode() == fsctx.Create {
|
||||
if fileInfo.Mode == fsctx.Create {
|
||||
overwrite = false
|
||||
}
|
||||
|
||||
@@ -247,7 +248,7 @@ func (handler Driver) Put(ctx context.Context, file fsctx.FileHeader) error {
|
||||
}
|
||||
|
||||
// 上传文件
|
||||
err := handler.bucket.PutObject(file.GetSavePath(), file, options...)
|
||||
err := handler.bucket.PutObject(fileInfo.SavePath, file, options...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -411,11 +412,12 @@ func (handler Driver) Token(ctx context.Context, ttl int64, uploadSession *seria
|
||||
}
|
||||
|
||||
// 上传策略
|
||||
savePath := file.Info().SavePath
|
||||
postPolicy := UploadPolicy{
|
||||
Expiration: time.Now().UTC().Add(time.Duration(ttl) * time.Second).Format(time.RFC3339),
|
||||
Conditions: []interface{}{
|
||||
map[string]string{"bucket": handler.Policy.BucketName},
|
||||
[]string{"starts-with", "$key", path.Dir(file.GetSavePath())},
|
||||
[]string{"starts-with", "$key", path.Dir(savePath)},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -424,7 +426,7 @@ func (handler Driver) Token(ctx context.Context, ttl int64, uploadSession *seria
|
||||
[]interface{}{"content-length-range", 0, handler.Policy.MaxSize})
|
||||
}
|
||||
|
||||
return handler.getUploadCredential(ctx, postPolicy, callbackPolicy, ttl, file.GetSavePath())
|
||||
return handler.getUploadCredential(ctx, postPolicy, callbackPolicy, ttl, savePath)
|
||||
}
|
||||
|
||||
func (handler Driver) getUploadCredential(ctx context.Context, policy UploadPolicy, callback CallbackPolicy, TTL int64, savePath string) (serializer.UploadCredential, error) {
|
||||
|
||||
@@ -150,12 +150,13 @@ func (handler Driver) Put(ctx context.Context, file fsctx.FileHeader) error {
|
||||
credentialTTL := model.GetIntSetting("upload_credential_timeout", 3600)
|
||||
|
||||
// 生成上传策略
|
||||
fileInfo := file.Info()
|
||||
putPolicy := storage.PutPolicy{
|
||||
// 指定为覆盖策略
|
||||
Scope: fmt.Sprintf("%s:%s", handler.Policy.BucketName, file.GetSavePath()),
|
||||
SaveKey: file.GetSavePath(),
|
||||
Scope: fmt.Sprintf("%s:%s", handler.Policy.BucketName, fileInfo.SavePath),
|
||||
SaveKey: fileInfo.SavePath,
|
||||
ForceSaveKey: true,
|
||||
FsizeLimit: int64(file.GetSize()),
|
||||
FsizeLimit: int64(fileInfo.Size),
|
||||
}
|
||||
// 是否开启了MIMEType限制
|
||||
if handler.Policy.OptionsSerialized.MimeType != "" {
|
||||
@@ -177,7 +178,7 @@ func (handler Driver) Put(ctx context.Context, file fsctx.FileHeader) error {
|
||||
}
|
||||
|
||||
// 开始上传
|
||||
err = formUploader.Put(ctx, &ret, token.Token, file.GetSavePath(), file, int64(file.GetSize()), &putExtra)
|
||||
err = formUploader.Put(ctx, &ret, token.Token, fileInfo.SavePath, file, int64(fileInfo.Size), &putExtra)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -285,7 +286,7 @@ func (handler Driver) Token(ctx context.Context, ttl int64, uploadSession *seria
|
||||
CallbackURL: apiURL.String(),
|
||||
CallbackBody: `{"name":"$(fname)","source_name":"$(key)","size":$(fsize),"pic_info":"$(imageInfo.width),$(imageInfo.height)"}`,
|
||||
CallbackBodyType: "application/json",
|
||||
SaveKey: file.GetSavePath(),
|
||||
SaveKey: file.Info().SavePath,
|
||||
ForceSaveKey: true,
|
||||
FsizeLimit: int64(handler.Policy.MaxSize),
|
||||
}
|
||||
|
||||
@@ -140,11 +140,12 @@ func (handler Driver) Put(ctx context.Context, file fsctx.FileHeader) error {
|
||||
credentialTTL := model.GetIntSetting("upload_credential_timeout", 3600)
|
||||
|
||||
// 生成上传策略
|
||||
fileInfo := file.Info()
|
||||
policy := serializer.UploadPolicy{
|
||||
SavePath: path.Dir(file.GetSavePath()),
|
||||
FileName: path.Base(file.GetSavePath()),
|
||||
SavePath: path.Dir(fileInfo.SavePath),
|
||||
FileName: path.Base(fileInfo.FileName),
|
||||
AutoRename: false,
|
||||
MaxSize: file.GetSize(),
|
||||
MaxSize: fileInfo.Size,
|
||||
}
|
||||
credential, err := handler.getUploadCredential(ctx, policy, int64(credentialTTL))
|
||||
if err != nil {
|
||||
@@ -152,11 +153,11 @@ func (handler Driver) Put(ctx context.Context, file fsctx.FileHeader) error {
|
||||
}
|
||||
|
||||
// 对文件名进行URLEncode
|
||||
fileName := url.QueryEscape(path.Base(file.GetSavePath()))
|
||||
fileName := url.QueryEscape(path.Base(fileInfo.SavePath))
|
||||
|
||||
// 决定是否要禁用文件覆盖
|
||||
overwrite := "true"
|
||||
if file.GetMode() != fsctx.Create {
|
||||
if fileInfo.Mode != fsctx.Create {
|
||||
overwrite = "false"
|
||||
}
|
||||
|
||||
@@ -170,7 +171,7 @@ func (handler Driver) Put(ctx context.Context, file fsctx.FileHeader) error {
|
||||
"X-Cr-FileName": {fileName},
|
||||
"X-Cr-Overwrite": {overwrite},
|
||||
}),
|
||||
request.WithContentLength(int64(file.GetSize())),
|
||||
request.WithContentLength(int64(fileInfo.Size)),
|
||||
request.WithTimeout(time.Duration(0)),
|
||||
request.WithMasterMeta(),
|
||||
request.WithSlaveMeta(handler.Policy.AccessKey),
|
||||
|
||||
@@ -206,7 +206,7 @@ func (handler Driver) Put(ctx context.Context, file fsctx.FileHeader) error {
|
||||
|
||||
uploader := s3manager.NewUploader(handler.sess)
|
||||
|
||||
dst := file.GetSavePath()
|
||||
dst := file.Info().SavePath
|
||||
_, err := uploader.Upload(&s3manager.UploadInput{
|
||||
Bucket: &handler.Policy.BucketName,
|
||||
Key: &dst,
|
||||
@@ -331,11 +331,12 @@ func (handler Driver) Token(ctx context.Context, ttl int64, uploadSession *seria
|
||||
apiURL := siteURL.ResolveReference(apiBaseURI)
|
||||
|
||||
// 上传策略
|
||||
savePath := file.Info().SavePath
|
||||
putPolicy := UploadPolicy{
|
||||
Expiration: time.Now().UTC().Add(time.Duration(ttl) * time.Second).Format(time.RFC3339),
|
||||
Conditions: []interface{}{
|
||||
map[string]string{"bucket": handler.Policy.BucketName},
|
||||
[]string{"starts-with", "$key", file.GetSavePath()},
|
||||
[]string{"starts-with", "$key", savePath},
|
||||
[]string{"starts-with", "$success_action_redirect", apiURL.String()},
|
||||
[]string{"starts-with", "$name", ""},
|
||||
[]string{"starts-with", "$Content-Type", ""},
|
||||
@@ -349,7 +350,7 @@ func (handler Driver) Token(ctx context.Context, ttl int64, uploadSession *seria
|
||||
}
|
||||
|
||||
// 生成上传凭证
|
||||
return handler.getUploadCredential(ctx, putPolicy, apiURL, file.GetSavePath())
|
||||
return handler.getUploadCredential(ctx, putPolicy, apiURL, savePath)
|
||||
}
|
||||
|
||||
// Meta 获取文件信息
|
||||
|
||||
@@ -57,7 +57,7 @@ func (d *Driver) Put(ctx context.Context, file fsctx.FileHeader) error {
|
||||
|
||||
req := serializer.SlaveTransferReq{
|
||||
Src: src,
|
||||
Dst: file.GetSavePath(),
|
||||
Dst: file.Info().SavePath,
|
||||
Policy: d.policy,
|
||||
}
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ func (handler Driver) Put(ctx context.Context, file fsctx.FileHeader) error {
|
||||
Password: handler.Policy.SecretKey,
|
||||
})
|
||||
err := up.Put(&upyun.PutObjectConfig{
|
||||
Path: file.GetSavePath(),
|
||||
Path: file.Info().SavePath,
|
||||
Reader: file,
|
||||
})
|
||||
|
||||
@@ -319,14 +319,15 @@ func (handler Driver) Token(ctx context.Context, ttl int64, uploadSession *seria
|
||||
apiURL := siteURL.ResolveReference(apiBaseURI)
|
||||
|
||||
// 上传策略
|
||||
fileInfo := file.Info()
|
||||
putPolicy := UploadPolicy{
|
||||
Bucket: handler.Policy.BucketName,
|
||||
// TODO escape
|
||||
SaveKey: file.GetSavePath(),
|
||||
SaveKey: fileInfo.SavePath,
|
||||
Expiration: time.Now().Add(time.Duration(ttl) * time.Second).Unix(),
|
||||
CallbackURL: apiURL.String(),
|
||||
ContentLength: file.GetSize(),
|
||||
ContentLengthRange: fmt.Sprintf("0,%d", file.GetSize()),
|
||||
ContentLength: fileInfo.Size,
|
||||
ContentLengthRange: fmt.Sprintf("0,%d", fileInfo.Size),
|
||||
AllowFileType: strings.Join(handler.Policy.OptionsSerialized.FileType, ","),
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user