Skip to content

Commit

Permalink
Merge pull request #62 from ufilesdk-dev/dev_cwb
Browse files Browse the repository at this point in the history
[feature]支持UploadCopyPart
  • Loading branch information
ufo2243 authored Jul 18, 2023
2 parents 1198c40 + 306645f commit f40dbe1
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
42 changes: 42 additions & 0 deletions file_mutipart_upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,48 @@ func (u *UFileRequest) UploadPart(buf *bytes.Buffer, state *MultipartState, part
return nil
}

//UploadPartCopy 实现从一个已存在的Object中拷贝数据来上传一个Part。
func (u *UFileRequest) UploadPartCopy(state *MultipartState, partNumber int, sourceBucketName, sourceObject string, offset, size int64) error {
query := &url.Values{}
query.Add("uploadId", state.uploadID)
query.Add("partNumber", strconv.Itoa(partNumber))

reqURL := u.genFileURL(state.keyName) + "?" + query.Encode()
req, err := http.NewRequest("PUT", reqURL, nil)
if err != nil {
return err
}
req.Header.Add("X-Ufile-Copy-Source", fmt.Sprintf("/%s/%s", sourceBucketName, sourceObject))
req.Header.Add("X-Ufile-Copy-Source-Range", fmt.Sprintf("bytes=%d-%d", offset, offset+size-1))
req.Header.Add("Content-Type", state.mimeType)
authorization := u.Auth.Authorization("PUT", u.BucketName, state.keyName, req.Header)
req.Header.Add("Authorization", authorization)

resp, err := u.requestWithResp(req)
if err != nil {
return err
}

if !VerifyHTTPCode(resp.StatusCode) {
err = u.responseParse(resp)
if err != nil {
return err
}
return fmt.Errorf("Remote response code is %d - %s not 2xx call DumpResponse(true) show details",
resp.StatusCode, http.StatusText(resp.StatusCode))
}
defer resp.Body.Close()

etag := strings.Trim(resp.Header.Get("Etag"), "\"") //为保证线程安全,这里就不保留 lastResponse
if etag == "" {
etag = strings.Trim(resp.Header.Get("ETag"), "\"") //为保证线程安全,这里就不保留 lastResponse
}
state.mux.Lock()
state.etags[partNumber] = etag
state.mux.Unlock()
return nil
}

//FinishMultipartUpload 完成分片上传。分片上传必须要调用的接口。
//state 参数是 InitiateMultipartUpload 返回的
func (u *UFileRequest) FinishMultipartUpload(state *MultipartState) error {
Expand Down
35 changes: 35 additions & 0 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"encoding/base64"
"encoding/binary"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
Expand Down Expand Up @@ -188,3 +189,37 @@ func structPrettyStr(data interface{}) string {
}
return ""
}

// FilePart is the file part definition
type FilePart struct {
Number int // Part number
Offset int64 // Part offset
Size int64 // Part size
}

// SplitFileByPartSize splits big file into parts by the size of parts.
// Splits the file by the part size. Returns the FilePart when error is nil.
func SplitFileByPartSize(fileSize, partSize int64) ([]FilePart, error) {
if fileSize <= 0 || partSize <= 0 {
return nil, errors.New("fileSize or partSize invalid")
}

var partN = fileSize / partSize
var parts []FilePart
var part = FilePart{}
for i := int64(0); i < partN; i++ {
part.Number = int(i)
part.Offset = i * partSize
part.Size = partSize
parts = append(parts, part)
}

if fileSize%partSize > 0 {
part.Number = len(parts)
part.Offset = int64(len(parts)) * partSize
part.Size = fileSize % partSize
parts = append(parts, part)
}

return parts, nil
}

0 comments on commit f40dbe1

Please sign in to comment.