feat(drivers/guangyapan): add md5-based instant upload support (#3034)

feat(guangyapan): add md5-based instant upload support

Co-authored-by: PIKACHUIM <PIKACHUIM@users.noreply.github.com>
This commit is contained in:
Pikachu Ren
2026-09-05 12:11:51 +08:00
committed by GitHub
parent d90d84906e
commit 6ad44605c0
2 changed files with 35 additions and 5 deletions
+7 -1
View File
@@ -394,7 +394,13 @@ func (d *GuangYaPan) Put(ctx context.Context, dstDir model.Obj, file model.FileS
parentID := dstDir.GetID()
token, code, err := d.getUploadToken(ctx, parentID, name, file.GetSize())
// 优先秒传:先计算文件 MD5,后端命中相同文件时直接秒传完成,无需真实上传。
md5sum, err := d.fileMD5(file, up)
if err != nil {
return nil, err
}
token, code, err := d.getUploadToken(ctx, parentID, name, file.GetSize(), md5sum)
if err != nil {
return nil, err
}
+28 -4
View File
@@ -133,15 +133,39 @@ func (d *GuangYaPan) waitTaskDone(ctx context.Context, taskID string) error {
// --- Upload helpers ---
func (d *GuangYaPan) getUploadToken(ctx context.Context, parentID, name string, size int64) (*uploadTokenData, int, error) {
// fileMD5 returns the MD5 of the file content, computing it from the stream when
// the caller did not provide it (e.g. local uploads). The computed hash is used
// to attempt instant upload (秒传) before falling back to the real OSS upload.
// For force-stream uploads the whole file would have to be buffered just to hash
// it, which defeats the purpose of streaming, so we skip 秒传 in that case.
func (d *GuangYaPan) fileMD5(file model.FileStreamer, up driver.UpdateProgress) (string, error) {
if md5sum := file.GetHash().GetHash(utils.MD5); len(md5sum) == utils.MD5.Width {
return md5sum, nil
}
if file.IsForceStreamUpload() {
return "", nil
}
_, md5sum, err := streamPkg.CacheFullAndHash(file, &up, utils.MD5)
if err != nil {
return "", err
}
return md5sum, nil
}
func (d *GuangYaPan) getUploadToken(ctx context.Context, parentID, name string, size int64, md5sum string) (*uploadTokenData, int, error) {
var out uploadTokenResp
res := map[string]any{
"fileSize": size,
}
if md5sum != "" {
// 秒传:后端根据 md5 判断文件是否已存在,命中则返回 code 156 秒传完成。
res["md5"] = md5sum
}
err := d.postAPI(ctx, "/nd.bizuserres.s/v1/get_res_center_token", map[string]any{
"capacity": 2,
"name": name,
"parentId": parentID,
"res": map[string]any{
"fileSize": size,
},
"res": res,
}, &out)
if err != nil {
return nil, 0, err