|
@@ -5,6 +5,7 @@ import (
|
|
|
"crypto/md5"
|
|
"crypto/md5"
|
|
|
"encoding/base64"
|
|
"encoding/base64"
|
|
|
"encoding/xml"
|
|
"encoding/xml"
|
|
|
|
|
+ "hash"
|
|
|
"hash/crc64"
|
|
"hash/crc64"
|
|
|
"io"
|
|
"io"
|
|
|
"io/ioutil"
|
|
"io/ioutil"
|
|
@@ -93,7 +94,9 @@ func (bucket Bucket) DoPutObject(request *PutObjectRequest, options []Option) (*
|
|
|
options = addContentType(options, request.ObjectKey)
|
|
options = addContentType(options, request.ObjectKey)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- resp, err := bucket.do("PUT", request.ObjectKey, "", "", options, request.Reader)
|
|
|
|
|
|
|
+ listener := getProgressListener(options)
|
|
|
|
|
+
|
|
|
|
|
+ resp, err := bucket.do("PUT", request.ObjectKey, "", "", options, request.Reader, listener)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return nil, err
|
|
return nil, err
|
|
|
}
|
|
}
|
|
@@ -185,7 +188,7 @@ func (bucket Bucket) GetObjectToFile(objectKey, filePath string, options ...Opti
|
|
|
// error 操作无错误为nil,非nil为错误信息。
|
|
// error 操作无错误为nil,非nil为错误信息。
|
|
|
//
|
|
//
|
|
|
func (bucket Bucket) DoGetObject(request *GetObjectRequest, options []Option) (*GetObjectResult, error) {
|
|
func (bucket Bucket) DoGetObject(request *GetObjectRequest, options []Option) (*GetObjectResult, error) {
|
|
|
- resp, err := bucket.do("GET", request.ObjectKey, "", "", options, nil)
|
|
|
|
|
|
|
+ resp, err := bucket.do("GET", request.ObjectKey, "", "", options, nil, nil)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return nil, err
|
|
return nil, err
|
|
|
}
|
|
}
|
|
@@ -194,14 +197,21 @@ func (bucket Bucket) DoGetObject(request *GetObjectRequest, options []Option) (*
|
|
|
Response: resp,
|
|
Response: resp,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // crc
|
|
|
|
|
+ var crcCalc hash.Hash64
|
|
|
hasRange, _, _ := isOptionSet(options, HTTPHeaderRange)
|
|
hasRange, _, _ := isOptionSet(options, HTTPHeaderRange)
|
|
|
if bucket.getConfig().IsEnableCRC && !hasRange {
|
|
if bucket.getConfig().IsEnableCRC && !hasRange {
|
|
|
- crcCalc := crc64.New(crcTable())
|
|
|
|
|
- resp.Body = ioutil.NopCloser(io.TeeReader(resp.Body, crcCalc))
|
|
|
|
|
|
|
+ crcCalc = crc64.New(crcTable())
|
|
|
result.ServerCRC = resp.ServerCRC
|
|
result.ServerCRC = resp.ServerCRC
|
|
|
result.ClientCRC = crcCalc
|
|
result.ClientCRC = crcCalc
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // progress
|
|
|
|
|
+ listener := getProgressListener(options)
|
|
|
|
|
+
|
|
|
|
|
+ contentLen, _ := strconv.ParseInt(resp.Headers.Get(HTTPHeaderContentLength), 10, 64)
|
|
|
|
|
+ resp.Body = ioutil.NopCloser(TeeReader(resp.Body, crcCalc, contentLen, listener, nil))
|
|
|
|
|
+
|
|
|
return result, nil
|
|
return result, nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -221,7 +231,7 @@ func (bucket Bucket) DoGetObject(request *GetObjectRequest, options []Option) (*
|
|
|
func (bucket Bucket) CopyObject(srcObjectKey, destObjectKey string, options ...Option) (CopyObjectResult, error) {
|
|
func (bucket Bucket) CopyObject(srcObjectKey, destObjectKey string, options ...Option) (CopyObjectResult, error) {
|
|
|
var out CopyObjectResult
|
|
var out CopyObjectResult
|
|
|
options = append(options, CopySource(bucket.BucketName, url.QueryEscape(srcObjectKey)))
|
|
options = append(options, CopySource(bucket.BucketName, url.QueryEscape(srcObjectKey)))
|
|
|
- resp, err := bucket.do("PUT", destObjectKey, "", "", options, nil)
|
|
|
|
|
|
|
+ resp, err := bucket.do("PUT", destObjectKey, "", "", options, nil, nil)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return out, err
|
|
return out, err
|
|
|
}
|
|
}
|
|
@@ -274,7 +284,7 @@ func (bucket Bucket) copy(srcObjectKey, destBucketName, destObjectKey string, op
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return out, err
|
|
return out, err
|
|
|
}
|
|
}
|
|
|
- resp, err := bucket.Client.Conn.Do("PUT", destBucketName, destObjectKey, "", "", headers, nil, 0)
|
|
|
|
|
|
|
+ resp, err := bucket.Client.Conn.Do("PUT", destBucketName, destObjectKey, "", "", headers, nil, 0, nil)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return out, err
|
|
return out, err
|
|
|
}
|
|
}
|
|
@@ -330,13 +340,16 @@ func (bucket Bucket) DoAppendObject(request *AppendObjectRequest, options []Opti
|
|
|
handleOptions(headers, opts)
|
|
handleOptions(headers, opts)
|
|
|
|
|
|
|
|
var initCRC uint64
|
|
var initCRC uint64
|
|
|
- isCRCSet, initCRCStr, _ := isOptionSet(options, initCRC64)
|
|
|
|
|
|
|
+ isCRCSet, initCRCOpt, _ := isOptionSet(options, initCRC64)
|
|
|
if isCRCSet {
|
|
if isCRCSet {
|
|
|
- initCRC, _ = strconv.ParseUint(initCRCStr, 10, 64)
|
|
|
|
|
|
|
+ initCRC = initCRCOpt.(uint64)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ listener := getProgressListener(options)
|
|
|
|
|
+
|
|
|
handleOptions(headers, opts)
|
|
handleOptions(headers, opts)
|
|
|
- resp, err := bucket.Client.Conn.Do("POST", bucket.BucketName, request.ObjectKey, params, params, headers, request.Reader, initCRC)
|
|
|
|
|
|
|
+ resp, err := bucket.Client.Conn.Do("POST", bucket.BucketName, request.ObjectKey, params, params, headers,
|
|
|
|
|
+ request.Reader, initCRC, listener)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return nil, err
|
|
return nil, err
|
|
|
}
|
|
}
|
|
@@ -366,7 +379,7 @@ func (bucket Bucket) DoAppendObject(request *AppendObjectRequest, options []Opti
|
|
|
// error 操作无错误为nil,非nil为错误信息。
|
|
// error 操作无错误为nil,非nil为错误信息。
|
|
|
//
|
|
//
|
|
|
func (bucket Bucket) DeleteObject(objectKey string) error {
|
|
func (bucket Bucket) DeleteObject(objectKey string) error {
|
|
|
- resp, err := bucket.do("DELETE", objectKey, "", "", nil, nil)
|
|
|
|
|
|
|
+ resp, err := bucket.do("DELETE", objectKey, "", "", nil, nil, nil)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
@@ -389,9 +402,8 @@ func (bucket Bucket) DeleteObjects(objectKeys []string, options ...Option) (Dele
|
|
|
for _, key := range objectKeys {
|
|
for _, key := range objectKeys {
|
|
|
dxml.Objects = append(dxml.Objects, DeleteObject{Key: key})
|
|
dxml.Objects = append(dxml.Objects, DeleteObject{Key: key})
|
|
|
}
|
|
}
|
|
|
- isQuietStr, _ := findOption(options, deleteObjectsQuiet, "FALSE")
|
|
|
|
|
- isQuiet, _ := strconv.ParseBool(isQuietStr)
|
|
|
|
|
- dxml.Quiet = isQuiet
|
|
|
|
|
|
|
+ isQuiet, _ := findOption(options, deleteObjectsQuiet, false)
|
|
|
|
|
+ dxml.Quiet = isQuiet.(bool)
|
|
|
encode := "&encoding-type=url"
|
|
encode := "&encoding-type=url"
|
|
|
|
|
|
|
|
bs, err := xml.Marshal(dxml)
|
|
bs, err := xml.Marshal(dxml)
|
|
@@ -406,7 +418,7 @@ func (bucket Bucket) DeleteObjects(objectKeys []string, options ...Option) (Dele
|
|
|
sum := md5.Sum(bs)
|
|
sum := md5.Sum(bs)
|
|
|
b64 := base64.StdEncoding.EncodeToString(sum[:])
|
|
b64 := base64.StdEncoding.EncodeToString(sum[:])
|
|
|
options = append(options, ContentMD5(b64))
|
|
options = append(options, ContentMD5(b64))
|
|
|
- resp, err := bucket.do("POST", "", "delete"+encode, "delete", options, buffer)
|
|
|
|
|
|
|
+ resp, err := bucket.do("POST", "", "delete"+encode, "delete", options, buffer, nil)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return out, err
|
|
return out, err
|
|
|
}
|
|
}
|
|
@@ -467,7 +479,7 @@ func (bucket Bucket) ListObjects(options ...Option) (ListObjectsResult, error) {
|
|
|
return out, err
|
|
return out, err
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- resp, err := bucket.do("GET", "", params, "", nil, nil)
|
|
|
|
|
|
|
+ resp, err := bucket.do("GET", "", params, "", nil, nil, nil)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return out, err
|
|
return out, err
|
|
|
}
|
|
}
|
|
@@ -508,7 +520,7 @@ func (bucket Bucket) SetObjectMeta(objectKey string, options ...Option) error {
|
|
|
// error 操作无错误为nil,非nil为错误信息。
|
|
// error 操作无错误为nil,非nil为错误信息。
|
|
|
//
|
|
//
|
|
|
func (bucket Bucket) GetObjectDetailedMeta(objectKey string, options ...Option) (http.Header, error) {
|
|
func (bucket Bucket) GetObjectDetailedMeta(objectKey string, options ...Option) (http.Header, error) {
|
|
|
- resp, err := bucket.do("HEAD", objectKey, "", "", options, nil)
|
|
|
|
|
|
|
+ resp, err := bucket.do("HEAD", objectKey, "", "", options, nil, nil)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return nil, err
|
|
return nil, err
|
|
|
}
|
|
}
|
|
@@ -529,7 +541,7 @@ func (bucket Bucket) GetObjectDetailedMeta(objectKey string, options ...Option)
|
|
|
// error 操作无错误为nil,非nil为错误信息。
|
|
// error 操作无错误为nil,非nil为错误信息。
|
|
|
//
|
|
//
|
|
|
func (bucket Bucket) GetObjectMeta(objectKey string) (http.Header, error) {
|
|
func (bucket Bucket) GetObjectMeta(objectKey string) (http.Header, error) {
|
|
|
- resp, err := bucket.do("GET", objectKey, "?objectMeta", "", nil, nil)
|
|
|
|
|
|
|
+ resp, err := bucket.do("GET", objectKey, "?objectMeta", "", nil, nil, nil)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return nil, err
|
|
return nil, err
|
|
|
}
|
|
}
|
|
@@ -557,7 +569,7 @@ func (bucket Bucket) GetObjectMeta(objectKey string) (http.Header, error) {
|
|
|
//
|
|
//
|
|
|
func (bucket Bucket) SetObjectACL(objectKey string, objectACL ACLType) error {
|
|
func (bucket Bucket) SetObjectACL(objectKey string, objectACL ACLType) error {
|
|
|
options := []Option{ObjectACL(objectACL)}
|
|
options := []Option{ObjectACL(objectACL)}
|
|
|
- resp, err := bucket.do("PUT", objectKey, "acl", "acl", options, nil)
|
|
|
|
|
|
|
+ resp, err := bucket.do("PUT", objectKey, "acl", "acl", options, nil, nil)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
@@ -575,7 +587,7 @@ func (bucket Bucket) SetObjectACL(objectKey string, objectACL ACLType) error {
|
|
|
//
|
|
//
|
|
|
func (bucket Bucket) GetObjectACL(objectKey string) (GetObjectACLResult, error) {
|
|
func (bucket Bucket) GetObjectACL(objectKey string) (GetObjectACLResult, error) {
|
|
|
var out GetObjectACLResult
|
|
var out GetObjectACLResult
|
|
|
- resp, err := bucket.do("GET", objectKey, "acl", "acl", nil, nil)
|
|
|
|
|
|
|
+ resp, err := bucket.do("GET", objectKey, "acl", "acl", nil, nil, nil)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return out, err
|
|
return out, err
|
|
|
}
|
|
}
|
|
@@ -586,15 +598,15 @@ func (bucket Bucket) GetObjectACL(objectKey string) (GetObjectACLResult, error)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Private
|
|
// Private
|
|
|
-func (bucket Bucket) do(method, objectName, urlParams, subResource string,
|
|
|
|
|
- options []Option, data io.Reader) (*Response, error) {
|
|
|
|
|
|
|
+func (bucket Bucket) do(method, objectName, urlParams, subResource string, options []Option,
|
|
|
|
|
+ data io.Reader, listener ProgressListener) (*Response, error) {
|
|
|
headers := make(map[string]string)
|
|
headers := make(map[string]string)
|
|
|
err := handleOptions(headers, options)
|
|
err := handleOptions(headers, options)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return nil, err
|
|
return nil, err
|
|
|
}
|
|
}
|
|
|
return bucket.Client.Conn.Do(method, bucket.BucketName, objectName,
|
|
return bucket.Client.Conn.Do(method, bucket.BucketName, objectName,
|
|
|
- urlParams, subResource, headers, data, 0)
|
|
|
|
|
|
|
+ urlParams, subResource, headers, data, 0, listener)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func (bucket Bucket) getConfig() *Config {
|
|
func (bucket Bucket) getConfig() *Config {
|