add upload verification
This commit is contained in:
2
cos.go
2
cos.go
@@ -22,7 +22,7 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// Version current go sdk version
|
// Version current go sdk version
|
||||||
Version = "0.7.20"
|
Version = "0.7.21"
|
||||||
userAgent = "cos-go-sdk-v5/" + Version
|
userAgent = "cos-go-sdk-v5/" + Version
|
||||||
contentTypeXML = "application/xml"
|
contentTypeXML = "application/xml"
|
||||||
defaultServiceBaseURL = "http://service.cos.myqcloud.com"
|
defaultServiceBaseURL = "http://service.cos.myqcloud.com"
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ func main() {
|
|||||||
|
|
||||||
// Case1 多线程上传对象
|
// Case1 多线程上传对象
|
||||||
opt := &cos.MultiUploadOptions{
|
opt := &cos.MultiUploadOptions{
|
||||||
ThreadPoolSize: 3,
|
EnableVerification: true,
|
||||||
|
ThreadPoolSize: 5,
|
||||||
}
|
}
|
||||||
v, _, err := c.Object.Upload(
|
v, _, err := c.Object.Upload(
|
||||||
context.Background(), "gomulput1G", "./test1G", opt,
|
context.Background(), "gomulput1G", "./test1G", opt,
|
||||||
@@ -71,4 +72,5 @@ func main() {
|
|||||||
)
|
)
|
||||||
log_status(err)
|
log_status(err)
|
||||||
fmt.Printf("Case2 done, %v\n", v)
|
fmt.Printf("Case2 done, %v\n", v)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
12
helper.go
12
helper.go
@@ -6,6 +6,7 @@ import (
|
|||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"hash/crc64"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
@@ -33,6 +34,17 @@ func calSHA1Digest(msg []byte) []byte {
|
|||||||
return m.Sum(nil)
|
return m.Sum(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func calCRC64(fd io.Reader) (uint64, error) {
|
||||||
|
tb := crc64.MakeTable(crc64.ECMA)
|
||||||
|
hash := crc64.New(tb)
|
||||||
|
_, err := io.Copy(hash, fd)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
sum := hash.Sum64()
|
||||||
|
return sum, nil
|
||||||
|
}
|
||||||
|
|
||||||
// cloneRequest returns a clone of the provided *http.Request. The clone is a
|
// cloneRequest returns a clone of the provided *http.Request. The clone is a
|
||||||
// shallow copy of the struct and its Header map.
|
// shallow copy of the struct and its Header map.
|
||||||
func cloneRequest(r *http.Request) *http.Request {
|
func cloneRequest(r *http.Request) *http.Request {
|
||||||
|
|||||||
27
object.go
27
object.go
@@ -524,10 +524,11 @@ type Object struct {
|
|||||||
// MultiUploadOptions is the option of the multiupload,
|
// MultiUploadOptions is the option of the multiupload,
|
||||||
// ThreadPoolSize default is one
|
// ThreadPoolSize default is one
|
||||||
type MultiUploadOptions struct {
|
type MultiUploadOptions struct {
|
||||||
OptIni *InitiateMultipartUploadOptions
|
OptIni *InitiateMultipartUploadOptions
|
||||||
PartSize int64
|
PartSize int64
|
||||||
ThreadPoolSize int
|
ThreadPoolSize int
|
||||||
CheckPoint bool
|
CheckPoint bool
|
||||||
|
EnableVerification bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Chunk struct {
|
type Chunk struct {
|
||||||
@@ -738,11 +739,21 @@ func (s *ObjectService) Upload(ctx context.Context, name string, filepath string
|
|||||||
if opt == nil {
|
if opt == nil {
|
||||||
opt = &MultiUploadOptions{}
|
opt = &MultiUploadOptions{}
|
||||||
}
|
}
|
||||||
|
var localcrc uint64
|
||||||
// 1.Get the file chunk
|
// 1.Get the file chunk
|
||||||
totalBytes, chunks, partNum, err := SplitFileIntoChunks(filepath, opt.PartSize)
|
totalBytes, chunks, partNum, err := SplitFileIntoChunks(filepath, opt.PartSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
// 校验
|
||||||
|
if opt.EnableVerification {
|
||||||
|
fd, err := os.Open(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
defer fd.Close()
|
||||||
|
localcrc, err = calCRC64(fd)
|
||||||
|
}
|
||||||
// filesize=0 , use simple upload
|
// filesize=0 , use simple upload
|
||||||
if partNum == 0 {
|
if partNum == 0 {
|
||||||
var opt0 *ObjectPutOptions
|
var opt0 *ObjectPutOptions
|
||||||
@@ -881,8 +892,16 @@ func (s *ObjectService) Upload(ctx context.Context, name string, filepath string
|
|||||||
v, resp, err := s.CompleteMultipartUpload(context.Background(), name, uploadID, optcom)
|
v, resp, err := s.CompleteMultipartUpload(context.Background(), name, uploadID, optcom)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.AbortMultipartUpload(ctx, name, uploadID)
|
s.AbortMultipartUpload(ctx, name, uploadID)
|
||||||
|
return v, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if opt.EnableVerification {
|
||||||
|
scoscrc := resp.Header.Get("x-cos-hash-crc64ecma")
|
||||||
|
icoscrc, _ := strconv.ParseUint(scoscrc, 10, 64)
|
||||||
|
if icoscrc != localcrc {
|
||||||
|
return v, resp, fmt.Errorf("verification failed, want:%v, return:%v", localcrc, icoscrc)
|
||||||
|
}
|
||||||
|
}
|
||||||
return v, resp, err
|
return v, resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user