基于华为云obs预签名URL实现大文件分段上传
【摘要】 基于华为云obs预签名URL实现大文件分段上传
预签名URL前端直传的限制:单次上传对象大小范围是[0, 5GB],如果需要上传超过5GB的大文件,需要通过多段操作来分段上传。
多段上传前后端交互流程:
后端分段实现
// 多段上传-初始化(POST)
func InitiateMultipartUpload(key string) (uploadId string, err error) {
object := getObsClient()
input := &obs.CreateSignedUrlInput{}
input.Method = obs.HttpMethodPost
input.Key = key
input.Bucket = global.Config.OBSBucketName
input.Expires = global.Config.OBSExpires
input.SubResource = obs.SubResourceUploads
output, err := object.CreateSignedUrl(input)
if err != nil {
logrus.Errorf("创建预签名URL时发生错误,err:%+v\n", err)
return "", err
}
outputInit, err := object.InitiateMultipartUploadWithSignedUrl(output.SignedUrl, output.ActualSignedRequestHeaders)
if err != nil {
logrus.Errorf("初始化分传段任务时发生错误,err:%+v\n", err)
return "", err
}
return outputInit.UploadId, nil
}
// 多段上传-段上传(PUT)
func UploadPartWithPartNumber(key string, uploadId string, partNumber string) (string, error) {
object := getObsClient()
input := &obs.CreateSignedUrlInput{}
input.Method = obs.HttpMethodPut
input.Key = key
input.Bucket = global.Config.OBSBucketName
input.Expires = global.Config.OBSExpires
input.QueryParams = make(map[string]string)
input.QueryParams["uploadId"] = uploadId
input.QueryParams["partNumber"] = partNumber
output, err := object.CreateSignedUrl(input)
if err != nil {
logrus.Errorf("UploadPartWithPartNum: 多段上传时发生错误,err:%+v\n", err)
return "", err
}
return output.SignedUrl, nil
}
type ObsPart struct {
PartNumber int
ETag string
}
// 多段上传-合并段
func CompleteMultipartUpload(key string, uploadId string, parts []ObsPart) error {
object := getObsClient()
input := &obs.CompleteMultipartUploadInput{}
input.Key = key
input.Bucket = global.Config.OBSBucketName
input.UploadId = uploadId
inputParts := make([]obs.Part, len(parts))
for i, v := range parts {
p := inputParts[i]
p.PartNumber = v.PartNumber
p.ETag = v.ETag
inputParts[i] = p
}
input.Parts = inputParts
output, err := object.CompleteMultipartUpload(input)
if err != nil {
logrus.Errorf("CompleteMultipartUpload: 多段上传-合并段时发生错误,err:%+v\n", err)
logrus.Printf("output: %+v", output)
if obsError, ok := err.(obs.ObsError); ok {
logrus.Println(obsError.Code)
logrus.Println(obsError.Message)
} else {
logrus.Println(err)
}
return err
}
return nil
}
注意:前后端分段计算方式要保持一致,即分段大小统一。
ISSUE:
- Error code:
EntityTooSmall
- Description: Your proposed upload is smaller than the minimum allowed object size. Each part must be at least 5 MB in size, except the last part.
- 400 Bad Request
解决方案:分段上传时保证每段大小至少是5MB。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)