Browse Source

支持分块上传

feature_wq
Sydonian 8 months ago
parent
commit
3a90a6cb52
2 changed files with 136 additions and 0 deletions
  1. +129
    -0
      sdks/storage/cdsapi/object.go
  2. +7
    -0
      sdks/storage/filehash.go

+ 129
- 0
sdks/storage/cdsapi/object.go View File

@@ -535,3 +535,132 @@ func (c *ObjectService) GetPackageObjects(req ObjectGetPackageObjects) (*ObjectG


return nil, jsonResp.ToError() 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()
}

+ 7
- 0
sdks/storage/filehash.go View File

@@ -20,6 +20,7 @@ type FileHash string
const ( const (
FullHashPrefix = "Full" FullHashPrefix = "Full"
CompositeHashPrefix = "Comp" CompositeHashPrefix = "Comp"
EmptyHash = FileHash("Full0000000000000000000000000000000000000000000000000000000000000000")
) )


func (h *FileHash) GetPrefix() string { func (h *FileHash) GetPrefix() string {
@@ -30,6 +31,12 @@ func (h *FileHash) GetHash() string {
return string((*h)[4:]) return string((*h)[4:])
} }


// 由调用者保证Hash值有效
func (h *FileHash) GetHashBytes() []byte {
bytes, _ := hex.DecodeString(h.GetHash())
return bytes
}

func (h *FileHash) GetHashPrefix(len int) string { func (h *FileHash) GetHashPrefix(len int) string {
return string((*h)[4 : 4+len]) return string((*h)[4 : 4+len])
} }


Loading…
Cancel
Save