From 3a90a6cb529d80454dda1ae3d7329d150d7aa690 Mon Sep 17 00:00:00 2001 From: Sydonian <794346190@qq.com> Date: Tue, 4 Mar 2025 16:36:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=88=86=E5=9D=97=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sdks/storage/cdsapi/object.go | 129 ++++++++++++++++++++++++++++++++++ sdks/storage/filehash.go | 7 ++ 2 files changed, 136 insertions(+) diff --git a/sdks/storage/cdsapi/object.go b/sdks/storage/cdsapi/object.go index e5a8f61..5ceda5f 100644 --- a/sdks/storage/cdsapi/object.go +++ b/sdks/storage/cdsapi/object.go @@ -535,3 +535,132 @@ func (c *ObjectService) GetPackageObjects(req ObjectGetPackageObjects) (*ObjectG return nil, jsonResp.ToError() } + +const ObjectNewMultipartUploadPath = "/v1/object/newMultipartUpload" + +type ObjectNewMultipartUpload struct { + UserID cdssdk.UserID `json:"userID" binding:"required"` + PackageID cdssdk.PackageID `json:"packageID" binding:"required"` + Path string `json:"path" binding:"required"` +} + +type ObjectNewMultipartUploadResp struct { + Object cdssdk.Object `json:"object"` +} + +func (c *ObjectService) NewMultipartUpload(req ObjectNewMultipartUpload) (*ObjectNewMultipartUploadResp, error) { + url, err := url.JoinPath(c.baseURL, ObjectNewMultipartUploadPath) + if err != nil { + return nil, err + } + + resp, err := http2.PostJSON(url, http2.RequestParam{ + Body: req, + }) + if err != nil { + return nil, err + } + + jsonResp, err := ParseJSONResponse[response[ObjectNewMultipartUploadResp]](resp) + if err != nil { + return nil, err + } + + if jsonResp.Code == errorcode.OK { + return &jsonResp.Data, nil + } + + return nil, jsonResp.ToError() +} + +const ObjectUploadPartPath = "/v1/object/uploadPart" + +type ObjectUploadPart struct { + ObjectUploadPartInfo + File io.ReadCloser `json:"-"` +} + +type ObjectUploadPartInfo struct { + UserID cdssdk.UserID `json:"userID" binding:"required"` + ObjectID cdssdk.ObjectID `json:"objectID" binding:"required"` + Index int `json:"index"` +} + +type ObjectUploadPartResp struct{} + +func (c *ObjectService) UploadPart(req ObjectUploadPart) (*ObjectUploadPartResp, error) { + url, err := url.JoinPath(c.baseURL, ObjectUploadPartPath) + if err != nil { + return nil, err + } + + infoJSON, err := serder.ObjectToJSON(req) + if err != nil { + return nil, fmt.Errorf("upload info to json: %w", err) + } + + resp, err := http2.PostMultiPart(url, http2.MultiPartRequestParam{ + Form: map[string]string{"info": string(infoJSON)}, + Files: iterator.Array(&http2.IterMultiPartFile{ + FieldName: "file", + File: req.File, + }), + }) + if err != nil { + return nil, err + } + + contType := resp.Header.Get("Content-Type") + if strings.Contains(contType, http2.ContentTypeJSON) { + var err error + var codeResp response[ObjectUploadPartResp] + if codeResp, err = serder.JSONToObjectStreamEx[response[ObjectUploadPartResp]](resp.Body); err != nil { + return nil, fmt.Errorf("parsing response: %w", err) + } + + if codeResp.Code == errorcode.OK { + return &codeResp.Data, nil + } + + return nil, codeResp.ToError() + } + + return nil, fmt.Errorf("unknow response content type: %s", contType) +} + +const ObjectCompleteMultipartUploadPath = "/v1/object/completeMultipartUpload" + +type ObjectCompleteMultipartUpload struct { + UserID cdssdk.UserID `json:"userID" binding:"required"` + ObjectID cdssdk.ObjectID `json:"objectID" binding:"required"` + Indexes []int `json:"indexes" binding:"required"` +} + +type ObjectCompleteMultipartUploadResp struct { + Object cdssdk.Object `json:"object"` +} + +func (c *ObjectService) CompleteMultipartUpload(req ObjectCompleteMultipartUpload) (*ObjectCompleteMultipartUploadResp, error) { + url, err := url.JoinPath(c.baseURL, ObjectCompleteMultipartUploadPath) + if err != nil { + return nil, err + } + + resp, err := http2.PostJSON(url, http2.RequestParam{ + Body: req, + }) + if err != nil { + return nil, err + } + + jsonResp, err := ParseJSONResponse[response[ObjectCompleteMultipartUploadResp]](resp) + if err != nil { + return nil, err + } + + if jsonResp.Code == errorcode.OK { + return &jsonResp.Data, nil + } + + return nil, jsonResp.ToError() +} diff --git a/sdks/storage/filehash.go b/sdks/storage/filehash.go index d4f9df5..b60cc30 100644 --- a/sdks/storage/filehash.go +++ b/sdks/storage/filehash.go @@ -20,6 +20,7 @@ type FileHash string const ( FullHashPrefix = "Full" CompositeHashPrefix = "Comp" + EmptyHash = FileHash("Full0000000000000000000000000000000000000000000000000000000000000000") ) func (h *FileHash) GetPrefix() string { @@ -30,6 +31,12 @@ func (h *FileHash) GetHash() string { return string((*h)[4:]) } +// 由调用者保证Hash值有效 +func (h *FileHash) GetHashBytes() []byte { + bytes, _ := hex.DecodeString(h.GetHash()) + return bytes +} + func (h *FileHash) GetHashPrefix(len int) string { return string((*h)[4 : 4+len]) }