diff --git a/go.mod b/go.mod
index 4c5e5384b..d479ca991 100644
--- a/go.mod
+++ b/go.mod
@@ -7,7 +7,7 @@ require (
cloud.google.com/go/storage v1.30.1
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.2
- github.com/aliyun/aliyun-oss-go-sdk v2.1.8+incompatible
+ github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible
github.com/aws/aws-sdk-go v1.54.20
github.com/gophercloud/gophercloud v0.17.0
github.com/gophercloud/utils v0.0.0-20200204043447-9864b6f1f12f
@@ -41,7 +41,6 @@ require (
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
- github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/coreos/go-semver v0.3.1 // indirect
@@ -97,7 +96,6 @@ require (
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
- github.com/satori/go.uuid v1.2.0 // indirect
github.com/soheilhy/cmux v0.1.5 // indirect
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 // indirect
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
diff --git a/go.sum b/go.sum
index d911c18ff..e8345cf8d 100644
--- a/go.sum
+++ b/go.sum
@@ -28,15 +28,13 @@ github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3Q
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
-github.com/aliyun/aliyun-oss-go-sdk v2.1.8+incompatible h1:hLUNPbx10wawWW7DeNExvTrlb90db3UnnNTFKHZEFhE=
-github.com/aliyun/aliyun-oss-go-sdk v2.1.8+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
+github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g=
+github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/aws/aws-sdk-go v1.54.20 h1:FZ2UcXya7bUkvkpf7TaPmiL7EubK0go1nlXGLRwEsoo=
github.com/aws/aws-sdk-go v1.54.20/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
-github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA=
-github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
@@ -249,8 +247,6 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
-github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/auth.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/auth.go
index bc1e4fa3f..2eccf3163 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/auth.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/auth.go
@@ -6,6 +6,7 @@ import (
"crypto/sha1"
"crypto/sha256"
"encoding/base64"
+ "encoding/hex"
"fmt"
"hash"
"io"
@@ -13,6 +14,7 @@ import (
"sort"
"strconv"
"strings"
+ "time"
)
// headerSorter defines the key-value structure for storing the sorted data in signHeader.
@@ -44,11 +46,59 @@ func (conn Conn) getAdditionalHeaderKeys(req *http.Request) ([]string, map[strin
return keysList, keysMap
}
+// getAdditionalHeaderKeysV4 get exist key in http header
+func (conn Conn) getAdditionalHeaderKeysV4(req *http.Request) ([]string, map[string]string) {
+ var keysList []string
+ keysMap := make(map[string]string)
+ srcKeys := make(map[string]string)
+
+ for k := range req.Header {
+ srcKeys[strings.ToLower(k)] = ""
+ }
+
+ for _, v := range conn.config.AdditionalHeaders {
+ if _, ok := srcKeys[strings.ToLower(v)]; ok {
+ if !strings.EqualFold(v, HTTPHeaderContentMD5) && !strings.EqualFold(v, HTTPHeaderContentType) {
+ keysMap[strings.ToLower(v)] = ""
+ }
+ }
+ }
+
+ for k := range keysMap {
+ keysList = append(keysList, k)
+ }
+ sort.Strings(keysList)
+ return keysList, keysMap
+}
+
// signHeader signs the header and sets it as the authorization header.
-func (conn Conn) signHeader(req *http.Request, canonicalizedResource string) {
- akIf := conn.config.GetCredentials()
+func (conn Conn) signHeader(req *http.Request, canonicalizedResource string, credentials Credentials) {
+ akIf := credentials
authorizationStr := ""
- if conn.config.AuthVersion == AuthV2 {
+ if conn.config.AuthVersion == AuthV4 {
+ strDay := ""
+ strDate := req.Header.Get(HttpHeaderOssDate)
+ if strDate == "" {
+ strDate = req.Header.Get(HTTPHeaderDate)
+ t, _ := time.Parse(http.TimeFormat, strDate)
+ strDay = t.Format("20060102")
+ } else {
+ t, _ := time.Parse(timeFormatV4, strDate)
+ strDay = t.Format("20060102")
+ }
+ signHeaderProduct := conn.config.GetSignProduct()
+ signHeaderRegion := conn.config.GetSignRegion()
+
+ additionalList, _ := conn.getAdditionalHeaderKeysV4(req)
+ if len(additionalList) > 0 {
+ authorizationFmt := "OSS4-HMAC-SHA256 Credential=%v/%v/%v/" + signHeaderProduct + "/aliyun_v4_request,AdditionalHeaders=%v,Signature=%v"
+ additionnalHeadersStr := strings.Join(additionalList, ";")
+ authorizationStr = fmt.Sprintf(authorizationFmt, akIf.GetAccessKeyID(), strDay, signHeaderRegion, additionnalHeadersStr, conn.getSignedStrV4(req, canonicalizedResource, akIf.GetAccessKeySecret(), nil))
+ } else {
+ authorizationFmt := "OSS4-HMAC-SHA256 Credential=%v/%v/%v/" + signHeaderProduct + "/aliyun_v4_request,Signature=%v"
+ authorizationStr = fmt.Sprintf(authorizationFmt, akIf.GetAccessKeyID(), strDay, signHeaderRegion, conn.getSignedStrV4(req, canonicalizedResource, akIf.GetAccessKeySecret(), nil))
+ }
+ } else if conn.config.AuthVersion == AuthV2 {
additionalList, _ := conn.getAdditionalHeaderKeys(req)
if len(additionalList) > 0 {
authorizationFmt := "OSS2 AccessKeyId:%v,AdditionalHeaders:%v,Signature:%v"
@@ -107,17 +157,8 @@ func (conn Conn) getSignedStr(req *http.Request, canonicalizedResource string, k
h = hmac.New(func() hash.Hash { return sha256.New() }, []byte(keySecret))
}
- // convert sign to log for easy to view
if conn.config.LogLevel >= Debug {
- var signBuf bytes.Buffer
- for i := 0; i < len(signStr); i++ {
- if signStr[i] != '\n' {
- signBuf.WriteByte(signStr[i])
- } else {
- signBuf.WriteString("\\n")
- }
- }
- conn.config.WriteLog(Debug, "[Req:%p]signStr:%s\n", req, signBuf.String())
+ conn.config.WriteLog(Debug, "[Req:%p]signStr:%s\n", req, EscapeLFString(signStr))
}
io.WriteString(h, signStr)
@@ -126,6 +167,114 @@ func (conn Conn) getSignedStr(req *http.Request, canonicalizedResource string, k
return signedStr
}
+func (conn Conn) getSignedStrV4(req *http.Request, canonicalizedResource string, keySecret string, signingTime *time.Time) string {
+ // Find out the "x-oss-"'s address in header of the request
+ ossHeadersMap := make(map[string]string)
+ additionalList, additionalMap := conn.getAdditionalHeaderKeysV4(req)
+ for k, v := range req.Header {
+ lowKey := strings.ToLower(k)
+ if strings.EqualFold(lowKey, HTTPHeaderContentMD5) ||
+ strings.EqualFold(lowKey, HTTPHeaderContentType) ||
+ strings.HasPrefix(lowKey, "x-oss-") {
+ ossHeadersMap[lowKey] = strings.Trim(v[0], " ")
+ } else {
+ if _, ok := additionalMap[lowKey]; ok {
+ ossHeadersMap[lowKey] = strings.Trim(v[0], " ")
+ }
+ }
+ }
+
+ // get day,eg 20210914
+ //signingTime
+ signDate := ""
+ strDay := ""
+ if signingTime != nil {
+ signDate = signingTime.Format(timeFormatV4)
+ strDay = signingTime.Format(shortTimeFormatV4)
+ } else {
+ var t time.Time
+ // Required parameters
+ if date := req.Header.Get(HTTPHeaderDate); date != "" {
+ signDate = date
+ t, _ = time.Parse(http.TimeFormat, date)
+ }
+
+ if ossDate := req.Header.Get(HttpHeaderOssDate); ossDate != "" {
+ signDate = ossDate
+ t, _ = time.Parse(timeFormatV4, ossDate)
+ }
+
+ strDay = t.Format("20060102")
+ }
+
+ hs := newHeaderSorter(ossHeadersMap)
+
+ // Sort the ossHeadersMap by the ascending order
+ hs.Sort()
+
+ // Get the canonicalizedOSSHeaders
+ canonicalizedOSSHeaders := ""
+ for i := range hs.Keys {
+ canonicalizedOSSHeaders += hs.Keys[i] + ":" + hs.Vals[i] + "\n"
+ }
+
+ signStr := ""
+
+ // v4 signature
+ hashedPayload := DefaultContentSha256
+ if val := req.Header.Get(HttpHeaderOssContentSha256); val != "" {
+ hashedPayload = val
+ }
+
+ // subResource
+ resource := canonicalizedResource
+ subResource := ""
+ subPos := strings.LastIndex(canonicalizedResource, "?")
+ if subPos != -1 {
+ subResource = canonicalizedResource[subPos+1:]
+ resource = canonicalizedResource[0:subPos]
+ }
+
+ // get canonical request
+ canonicalReuqest := req.Method + "\n" + resource + "\n" + subResource + "\n" + canonicalizedOSSHeaders + "\n" + strings.Join(additionalList, ";") + "\n" + hashedPayload
+ rh := sha256.New()
+ io.WriteString(rh, canonicalReuqest)
+ hashedRequest := hex.EncodeToString(rh.Sum(nil))
+
+ if conn.config.LogLevel >= Debug {
+ conn.config.WriteLog(Debug, "[Req:%p]CanonicalRequest:%s\n", req, EscapeLFString(canonicalReuqest))
+ }
+
+ // Product & Region
+ signedStrV4Product := conn.config.GetSignProduct()
+ signedStrV4Region := conn.config.GetSignRegion()
+
+ signStr = "OSS4-HMAC-SHA256" + "\n" + signDate + "\n" + strDay + "/" + signedStrV4Region + "/" + signedStrV4Product + "/aliyun_v4_request" + "\n" + hashedRequest
+ if conn.config.LogLevel >= Debug {
+ conn.config.WriteLog(Debug, "[Req:%p]signStr:%s\n", req, EscapeLFString(signStr))
+ }
+
+ h1 := hmac.New(func() hash.Hash { return sha256.New() }, []byte("aliyun_v4"+keySecret))
+ io.WriteString(h1, strDay)
+ h1Key := h1.Sum(nil)
+
+ h2 := hmac.New(func() hash.Hash { return sha256.New() }, h1Key)
+ io.WriteString(h2, signedStrV4Region)
+ h2Key := h2.Sum(nil)
+
+ h3 := hmac.New(func() hash.Hash { return sha256.New() }, h2Key)
+ io.WriteString(h3, signedStrV4Product)
+ h3Key := h3.Sum(nil)
+
+ h4 := hmac.New(func() hash.Hash { return sha256.New() }, h3Key)
+ io.WriteString(h4, "aliyun_v4_request")
+ h4Key := h4.Sum(nil)
+
+ h := hmac.New(func() hash.Hash { return sha256.New() }, h4Key)
+ io.WriteString(h, signStr)
+ return fmt.Sprintf("%x", h.Sum(nil))
+}
+
func (conn Conn) getRtmpSignedStr(bucketName, channelName, playlistName string, expiration int64, keySecret string, params map[string]interface{}) string {
if params[HTTPParamAccessKeyID] == nil {
return ""
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/bucket.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/bucket.go
index 430252c02..26dea3bb2 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/bucket.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/bucket.go
@@ -2,6 +2,7 @@ package oss
import (
"bytes"
+ "context"
"crypto/md5"
"encoding/base64"
"encoding/xml"
@@ -9,6 +10,7 @@ import (
"hash"
"hash/crc64"
"io"
+ "io/ioutil"
"net/http"
"net/url"
"os"
@@ -28,11 +30,11 @@ type Bucket struct {
// objectKey the object key in UTF-8 encoding. The length must be between 1 and 1023, and cannot start with "/" or "\".
// reader io.Reader instance for reading the data for uploading
// options the options for uploading the object. The valid options here are CacheControl, ContentDisposition, ContentEncoding
-// Expires, ServerSideEncryption, ObjectACL and Meta. Refer to the link below for more details.
-// https://help.aliyun.com/document_detail/oss/api-reference/object/PutObject.html
//
-// error it's nil if no error, otherwise it's an error object.
+// Expires, ServerSideEncryption, ObjectACL and Meta. Refer to the link below for more details.
+// https://www.alibabacloud.com/help/en/object-storage-service/latest/putobject
//
+// error it's nil if no error, otherwise it's an error object.
func (bucket Bucket) PutObject(objectKey string, reader io.Reader, options ...Option) error {
opts := AddContentType(options, objectKey)
@@ -56,7 +58,6 @@ func (bucket Bucket) PutObject(objectKey string, reader io.Reader, options ...Op
// options the options for uploading the object. Refer to the parameter options in PutObject for more details.
//
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) PutObjectFromFile(objectKey, filePath string, options ...Option) error {
fd, err := os.Open(filePath)
if err != nil {
@@ -86,7 +87,6 @@ func (bucket Bucket) PutObjectFromFile(objectKey, filePath string, options ...Op
//
// Response the response from OSS.
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) DoPutObject(request *PutObjectRequest, options []Option) (*Response, error) {
isOptSet, _, _ := IsOptionSet(options, HTTPHeaderContentType)
if !isOptSet {
@@ -100,16 +100,26 @@ func (bucket Bucket) DoPutObject(request *PutObjectRequest, options []Option) (*
if err != nil {
return nil, err
}
-
if bucket.GetConfig().IsEnableCRC {
err = CheckCRC(resp, "DoPutObject")
if err != nil {
return resp, err
}
}
-
err = CheckRespCode(resp.StatusCode, []int{http.StatusOK})
-
+ body, _ := ioutil.ReadAll(resp.Body)
+ if len(body) > 0 {
+ if err != nil {
+ err = tryConvertServiceError(body, resp, err)
+ } else {
+ rb, _ := FindOption(options, responseBody, nil)
+ if rb != nil {
+ if rbody, ok := rb.(*[]byte); ok {
+ *rbody = body
+ }
+ }
+ }
+ }
return resp, err
}
@@ -117,12 +127,12 @@ func (bucket Bucket) DoPutObject(request *PutObjectRequest, options []Option) (*
//
// objectKey the object key.
// options the options for downloading the object. The valid values are: Range, IfModifiedSince, IfUnmodifiedSince, IfMatch,
-// IfNoneMatch, AcceptEncoding. For more details, please check out:
-// https://help.aliyun.com/document_detail/oss/api-reference/object/GetObject.html
+//
+// IfNoneMatch, AcceptEncoding. For more details, please check out:
+// https://www.alibabacloud.com/help/en/object-storage-service/latest/getobject
//
// io.ReadCloser reader instance for reading data from response. It must be called close() after the usage and only valid when error is nil.
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) GetObject(objectKey string, options ...Option) (io.ReadCloser, error) {
result, err := bucket.DoGetObject(&GetObjectRequest{objectKey}, options)
if err != nil {
@@ -139,7 +149,6 @@ func (bucket Bucket) GetObject(objectKey string, options ...Option) (io.ReadClos
// options the options for downloading the object. Refer to the parameter options in method GetObject for more details.
//
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) GetObjectToFile(objectKey, filePath string, options ...Option) error {
tempFilePath := filePath + TempFileSuffix
@@ -189,7 +198,6 @@ func (bucket Bucket) GetObjectToFile(objectKey, filePath string, options ...Opti
//
// GetObjectResult the result instance of getting the object.
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) DoGetObject(request *GetObjectRequest, options []Option) (*GetObjectResult, error) {
params, _ := GetRawParams(options)
resp, err := bucket.do("GET", request.ObjectKey, params, options, nil, nil)
@@ -224,13 +232,13 @@ func (bucket Bucket) DoGetObject(request *GetObjectRequest, options []Option) (*
// srcObjectKey the source object to copy.
// destObjectKey the target object to copy.
// options options for copying an object. You can specify the conditions of copy. The valid conditions are CopySourceIfMatch,
-// CopySourceIfNoneMatch, CopySourceIfModifiedSince, CopySourceIfUnmodifiedSince, MetadataDirective.
-// Also you can specify the target object's attributes, such as CacheControl, ContentDisposition, ContentEncoding, Expires,
-// ServerSideEncryption, ObjectACL, Meta. Refer to the link below for more details :
-// https://help.aliyun.com/document_detail/oss/api-reference/object/CopyObject.html
//
-// error it's nil if no error, otherwise it's an error object.
+// CopySourceIfNoneMatch, CopySourceIfModifiedSince, CopySourceIfUnmodifiedSince, MetadataDirective.
+// Also you can specify the target object's attributes, such as CacheControl, ContentDisposition, ContentEncoding, Expires,
+// ServerSideEncryption, ObjectACL, Meta. Refer to the link below for more details :
+// https://www.alibabacloud.com/help/en/object-storage-service/latest/copyobject
//
+// error it's nil if no error, otherwise it's an error object.
func (bucket Bucket) CopyObject(srcObjectKey, destObjectKey string, options ...Option) (CopyObjectResult, error) {
var out CopyObjectResult
@@ -263,12 +271,10 @@ func (bucket Bucket) CopyObject(srcObjectKey, destObjectKey string, options ...O
// options copy options, check out parameter options in function CopyObject for more details.
//
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) CopyObjectTo(destBucketName, destObjectKey, srcObjectKey string, options ...Option) (CopyObjectResult, error) {
return bucket.copy(srcObjectKey, destBucketName, destObjectKey, options...)
}
-//
// CopyObjectFrom copies the object to another bucket.
//
// srcBucketName source bucket name.
@@ -277,7 +283,6 @@ func (bucket Bucket) CopyObjectTo(destBucketName, destObjectKey, srcObjectKey st
// options copy options. Check out parameter options in function CopyObject.
//
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) CopyObjectFrom(srcBucketName, srcObjectKey, destObjectKey string, options ...Option) (CopyObjectResult, error) {
destBucketName := bucket.BucketName
var out CopyObjectResult
@@ -308,13 +313,19 @@ func (bucket Bucket) copy(srcObjectKey, destBucketName, destObjectKey string, op
return out, err
}
params := map[string]interface{}{}
- resp, err := bucket.Client.Conn.Do("PUT", destBucketName, destObjectKey, params, headers, nil, 0, nil)
+
+ ctxArg, _ := FindOption(options, contextArg, nil)
+ ctx, _ := ctxArg.(context.Context)
+
+ resp, err := bucket.Client.Conn.DoWithContext(ctx, "PUT", destBucketName, destObjectKey, params, headers, nil, 0, nil)
// get response header
respHeader, _ := FindOption(options, responseHeader, nil)
if respHeader != nil {
pRespHeader := respHeader.(*http.Header)
- *pRespHeader = resp.Headers
+ if resp != nil {
+ *pRespHeader = resp.Headers
+ }
}
if err != nil {
@@ -337,11 +348,11 @@ func (bucket Bucket) copy(srcObjectKey, destBucketName, destObjectKey string, op
// reader io.Reader. The read instance for reading the data to append.
// appendPosition the start position to append.
// destObjectProperties the options for the first appending, such as CacheControl, ContentDisposition, ContentEncoding,
-// Expires, ServerSideEncryption, ObjectACL.
+//
+// Expires, ServerSideEncryption, ObjectACL.
//
// int64 the next append position, it's valid when error is nil.
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) AppendObject(objectKey string, reader io.Reader, appendPosition int64, options ...Option) (int64, error) {
request := &AppendObjectRequest{
ObjectKey: objectKey,
@@ -364,7 +375,6 @@ func (bucket Bucket) AppendObject(objectKey string, reader io.Reader, appendPosi
//
// AppendObjectResult the result object for appending object.
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) DoAppendObject(request *AppendObjectRequest, options []Option) (*AppendObjectResult, error) {
params := map[string]interface{}{}
params["append"] = nil
@@ -383,14 +393,20 @@ func (bucket Bucket) DoAppendObject(request *AppendObjectRequest, options []Opti
listener := GetProgressListener(options)
handleOptions(headers, opts)
- resp, err := bucket.Client.Conn.Do("POST", bucket.BucketName, request.ObjectKey, params, headers,
+
+ ctxArg, _ := FindOption(options, contextArg, nil)
+ ctx, _ := ctxArg.(context.Context)
+
+ resp, err := bucket.Client.Conn.DoWithContext(ctx, "POST", bucket.BucketName, request.ObjectKey, params, headers,
request.Reader, initCRC, listener)
// get response header
respHeader, _ := FindOption(options, responseHeader, nil)
if respHeader != nil {
pRespHeader := respHeader.(*http.Header)
- *pRespHeader = resp.Headers
+ if resp != nil {
+ *pRespHeader = resp.Headers
+ }
}
if err != nil {
@@ -419,7 +435,6 @@ func (bucket Bucket) DoAppendObject(request *AppendObjectRequest, options []Opti
// objectKey the object key to delete.
//
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) DeleteObject(objectKey string, options ...Option) error {
params, _ := GetRawParams(options)
resp, err := bucket.do("DELETE", objectKey, params, options, nil, nil)
@@ -434,57 +449,35 @@ func (bucket Bucket) DeleteObject(objectKey string, options ...Option) error {
//
// objectKeys the object keys to delete.
// options the options for deleting objects.
-// Supported option is DeleteObjectsQuiet which means it will not return error even deletion failed (not recommended). By default it's not used.
+//
+// Supported option is DeleteObjectsQuiet which means it will not return error even deletion failed (not recommended). By default it's not used.
//
// DeleteObjectsResult the result object.
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) DeleteObjects(objectKeys []string, options ...Option) (DeleteObjectsResult, error) {
out := DeleteObjectsResult{}
dxml := deleteXML{}
for _, key := range objectKeys {
dxml.Objects = append(dxml.Objects, DeleteObject{Key: key})
}
-
isQuiet, _ := FindOption(options, deleteObjectsQuiet, false)
dxml.Quiet = isQuiet.(bool)
-
- bs, err := xml.Marshal(dxml)
+ xmlData := marshalDeleteObjectToXml(dxml)
+ body, err := bucket.DeleteMultipleObjectsXml(xmlData, options...)
if err != nil {
return out, err
}
- buffer := new(bytes.Buffer)
- buffer.Write(bs)
-
- contentType := http.DetectContentType(buffer.Bytes())
- options = append(options, ContentType(contentType))
- sum := md5.Sum(bs)
- b64 := base64.StdEncoding.EncodeToString(sum[:])
- options = append(options, ContentMD5(b64))
-
- params := map[string]interface{}{}
- params["delete"] = nil
- params["encoding-type"] = "url"
-
- resp, err := bucket.do("POST", "", params, options, buffer, nil)
- if err != nil {
- return out, err
- }
- defer resp.Body.Close()
-
deletedResult := DeleteObjectVersionsResult{}
if !dxml.Quiet {
- if err = xmlUnmarshal(resp.Body, &deletedResult); err == nil {
+ if err = xmlUnmarshal(strings.NewReader(body), &deletedResult); err == nil {
err = decodeDeleteObjectsResult(&deletedResult)
}
}
-
// Keep compatibility:need convert to struct DeleteObjectsResult
out.XMLName = deletedResult.XMLName
for _, v := range deletedResult.DeletedObjectsDetail {
out.DeletedObjects = append(out.DeletedObjects, v.Key)
}
-
return out, err
}
@@ -492,47 +485,56 @@ func (bucket Bucket) DeleteObjects(objectKeys []string, options ...Option) (Dele
//
// objectVersions the object keys and versions to delete.
// options the options for deleting objects.
-// Supported option is DeleteObjectsQuiet which means it will not return error even deletion failed (not recommended). By default it's not used.
+//
+// Supported option is DeleteObjectsQuiet which means it will not return error even deletion failed (not recommended). By default it's not used.
//
// DeleteObjectVersionsResult the result object.
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) DeleteObjectVersions(objectVersions []DeleteObject, options ...Option) (DeleteObjectVersionsResult, error) {
out := DeleteObjectVersionsResult{}
dxml := deleteXML{}
dxml.Objects = objectVersions
-
isQuiet, _ := FindOption(options, deleteObjectsQuiet, false)
dxml.Quiet = isQuiet.(bool)
-
- bs, err := xml.Marshal(dxml)
+ xmlData := marshalDeleteObjectToXml(dxml)
+ body, err := bucket.DeleteMultipleObjectsXml(xmlData, options...)
if err != nil {
return out, err
}
+ if !dxml.Quiet {
+ if err = xmlUnmarshal(strings.NewReader(body), &out); err == nil {
+ err = decodeDeleteObjectsResult(&out)
+ }
+ }
+ return out, err
+}
+
+// DeleteMultipleObjectsXml deletes multiple object or deletes multiple object versions.
+//
+// xmlData the object keys and versions to delete as the xml format.
+// options the options for deleting objects.
+//
+// string the result response body.
+// error it's nil if no error, otherwise it's an error.
+func (bucket Bucket) DeleteMultipleObjectsXml(xmlData string, options ...Option) (string, error) {
buffer := new(bytes.Buffer)
+ bs := []byte(xmlData)
buffer.Write(bs)
-
- contentType := http.DetectContentType(buffer.Bytes())
- options = append(options, ContentType(contentType))
+ options = append(options, ContentType("application/xml"))
sum := md5.Sum(bs)
b64 := base64.StdEncoding.EncodeToString(sum[:])
options = append(options, ContentMD5(b64))
-
params := map[string]interface{}{}
params["delete"] = nil
params["encoding-type"] = "url"
-
- resp, err := bucket.do("POST", "", params, options, buffer, nil)
+ resp, err := bucket.doInner("POST", "", params, options, buffer, nil)
if err != nil {
- return out, err
+ return "", err
}
defer resp.Body.Close()
- if !dxml.Quiet {
- if err = xmlUnmarshal(resp.Body, &out); err == nil {
- err = decodeDeleteObjectsResult(&out)
- }
- }
+ body, err := ioutil.ReadAll(resp.Body)
+ out := string(body)
return out, err
}
@@ -541,7 +543,6 @@ func (bucket Bucket) DeleteObjectVersions(objectVersions []DeleteObject, options
// bool flag of object's existence (true:exists; false:non-exist) when error is nil.
//
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) IsObjectExist(objectKey string, options ...Option) (bool, error) {
_, err := bucket.GetObjectMeta(objectKey, options...)
if err == nil {
@@ -561,23 +562,23 @@ func (bucket Bucket) IsObjectExist(objectKey string, options ...Option) (bool, e
// ListObjects lists the objects under the current bucket.
//
// options it contains all the filters for listing objects.
-// It could specify a prefix filter on object keys, the max keys count to return and the object key marker and the delimiter for grouping object names.
-// The key marker means the returned objects' key must be greater than it in lexicographic order.
//
-// For example, if the bucket has 8 objects, my-object-1, my-object-11, my-object-2, my-object-21,
-// my-object-22, my-object-3, my-object-31, my-object-32. If the prefix is my-object-2 (no other filters), then it returns
-// my-object-2, my-object-21, my-object-22 three objects. If the marker is my-object-22 (no other filters), then it returns
-// my-object-3, my-object-31, my-object-32 three objects. If the max keys is 5, then it returns 5 objects.
-// The three filters could be used together to achieve filter and paging functionality.
-// If the prefix is the folder name, then it could list all files under this folder (including the files under its subfolders).
-// But if the delimiter is specified with '/', then it only returns that folder's files (no subfolder's files). The direct subfolders are in the commonPrefixes properties.
-// For example, if the bucket has three objects fun/test.jpg, fun/movie/001.avi, fun/movie/007.avi. And if the prefix is "fun/", then it returns all three objects.
-// But if the delimiter is '/', then only "fun/test.jpg" is returned as files and fun/movie/ is returned as common prefix.
+// It could specify a prefix filter on object keys, the max keys count to return and the object key marker and the delimiter for grouping object names.
+// The key marker means the returned objects' key must be greater than it in lexicographic order.
//
-// For common usage scenario, check out sample/list_object.go.
+// For example, if the bucket has 8 objects, my-object-1, my-object-11, my-object-2, my-object-21,
+// my-object-22, my-object-3, my-object-31, my-object-32. If the prefix is my-object-2 (no other filters), then it returns
+// my-object-2, my-object-21, my-object-22 three objects. If the marker is my-object-22 (no other filters), then it returns
+// my-object-3, my-object-31, my-object-32 three objects. If the max keys is 5, then it returns 5 objects.
+// The three filters could be used together to achieve filter and paging functionality.
+// If the prefix is the folder name, then it could list all files under this folder (including the files under its subfolders).
+// But if the delimiter is specified with '/', then it only returns that folder's files (no subfolder's files). The direct subfolders are in the commonPrefixes properties.
+// For example, if the bucket has three objects fun/test.jpg, fun/movie/001.avi, fun/movie/007.avi. And if the prefix is "fun/", then it returns all three objects.
+// But if the delimiter is '/', then only "fun/test.jpg" is returned as files and fun/movie/ is returned as common prefix.
//
-// ListObjectsResult the return value after operation succeeds (only valid when error is nil).
+// For common usage scenario, check out sample/list_object.go.
//
+// ListObjectsResult the return value after operation succeeds (only valid when error is nil).
func (bucket Bucket) ListObjects(options ...Option) (ListObjectsResult, error) {
var out ListObjectsResult
@@ -587,7 +588,7 @@ func (bucket Bucket) ListObjects(options ...Option) (ListObjectsResult, error) {
return out, err
}
- resp, err := bucket.do("GET", "", params, options, nil, nil)
+ resp, err := bucket.doInner("GET", "", params, options, nil, nil)
if err != nil {
return out, err
}
@@ -602,8 +603,8 @@ func (bucket Bucket) ListObjects(options ...Option) (ListObjectsResult, error) {
return out, err
}
+// ListObjectsV2 lists the objects under the current bucket.
// Recommend to use ListObjectsV2 to replace ListObjects
-// ListOListObjectsV2bjects lists the objects under the current bucket.
// ListObjectsResultV2 the return value after operation succeeds (only valid when error is nil).
func (bucket Bucket) ListObjectsV2(options ...Option) (ListObjectsResultV2, error) {
var out ListObjectsResultV2
@@ -615,7 +616,7 @@ func (bucket Bucket) ListObjectsV2(options ...Option) (ListObjectsResultV2, erro
return out, err
}
- resp, err := bucket.do("GET", "", params, options, nil, nil)
+ resp, err := bucket.doInner("GET", "", params, options, nil, nil)
if err != nil {
return out, err
}
@@ -641,7 +642,7 @@ func (bucket Bucket) ListObjectVersions(options ...Option) (ListObjectVersionsRe
}
params["versions"] = nil
- resp, err := bucket.do("GET", "", params, options, nil, nil)
+ resp, err := bucket.doInner("GET", "", params, options, nil, nil)
if err != nil {
return out, err
}
@@ -660,10 +661,10 @@ func (bucket Bucket) ListObjectVersions(options ...Option) (ListObjectVersionsRe
//
// objectKey object
// options options for setting the metadata. The valid options are CacheControl, ContentDisposition, ContentEncoding, Expires,
-// ServerSideEncryption, and custom metadata.
//
-// error it's nil if no error, otherwise it's an error object.
+// ServerSideEncryption, and custom metadata.
//
+// error it's nil if no error, otherwise it's an error object.
func (bucket Bucket) SetObjectMeta(objectKey string, options ...Option) error {
options = append(options, MetadataDirective(MetaReplace))
_, err := bucket.CopyObject(objectKey, objectKey, options...)
@@ -674,11 +675,11 @@ func (bucket Bucket) SetObjectMeta(objectKey string, options ...Option) error {
//
// objectKey object key.
// options the constraints of the object. Only when the object meets the requirements this method will return the metadata. Otherwise returns error. Valid options are IfModifiedSince, IfUnmodifiedSince,
-// IfMatch, IfNoneMatch. For more details check out https://help.aliyun.com/document_detail/oss/api-reference/object/HeadObject.html
+//
+// IfMatch, IfNoneMatch. For more details check out https://www.alibabacloud.com/help/en/object-storage-service/latest/headobject
//
// http.Header object meta when error is nil.
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) GetObjectDetailedMeta(objectKey string, options ...Option) (http.Header, error) {
params, _ := GetRawParams(options)
resp, err := bucket.do("HEAD", objectKey, params, options, nil, nil)
@@ -699,7 +700,6 @@ func (bucket Bucket) GetObjectDetailedMeta(objectKey string, options ...Option)
//
// http.Header the object's metadata, valid when error is nil.
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) GetObjectMeta(objectKey string, options ...Option) (http.Header, error) {
params, _ := GetRawParams(options)
params["objectMeta"] = nil
@@ -728,7 +728,6 @@ func (bucket Bucket) GetObjectMeta(objectKey string, options ...Option) (http.He
// objectAcl object ACL. Valid options are PrivateACL, PublicReadACL, PublicReadWriteACL.
//
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) SetObjectACL(objectKey string, objectACL ACLType, options ...Option) error {
options = append(options, ObjectACL(objectACL))
params, _ := GetRawParams(options)
@@ -747,7 +746,6 @@ func (bucket Bucket) SetObjectACL(objectKey string, objectACL ACLType, options .
//
// GetObjectACLResult the result object when error is nil. GetObjectACLResult.Acl is the object ACL.
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) GetObjectACL(objectKey string, options ...Option) (GetObjectACLResult, error) {
var out GetObjectACLResult
params, _ := GetRawParams(options)
@@ -774,7 +772,6 @@ func (bucket Bucket) GetObjectACL(objectKey string, options ...Option) (GetObjec
// targetObjectKey the target object key to point to.
//
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) PutSymlink(symObjectKey string, targetObjectKey string, options ...Option) error {
options = append(options, symlinkTarget(url.QueryEscape(targetObjectKey)))
params, _ := GetRawParams(options)
@@ -793,8 +790,8 @@ func (bucket Bucket) PutSymlink(symObjectKey string, targetObjectKey string, opt
// objectKey the symlink object's key.
//
// error it's nil if no error, otherwise it's an error object.
-// When error is nil, the target file key is in the X-Oss-Symlink-Target header of the returned object.
//
+// When error is nil, the target file key is in the X-Oss-Symlink-Target header of the returned object.
func (bucket Bucket) GetSymlink(objectKey string, options ...Option) (http.Header, error) {
params, _ := GetRawParams(options)
params["symlink"] = nil
@@ -824,7 +821,6 @@ func (bucket Bucket) GetSymlink(objectKey string, options ...Option) (http.Heade
// objectKey object key to restore.
//
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) RestoreObject(objectKey string, options ...Option) error {
params, _ := GetRawParams(options)
params["restore"] = nil
@@ -895,8 +891,12 @@ func (bucket Bucket) RestoreObjectXML(objectKey, configXML string, options ...Op
//
// string returns the signed URL, when error is nil.
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) SignURL(objectKey string, method HTTPMethod, expiredInSec int64, options ...Option) (string, error) {
+ err := CheckObjectNameEx(objectKey, isVerifyObjectStrict(bucket.GetConfig()))
+ if err != nil {
+ return "", err
+ }
+
if expiredInSec < 0 {
return "", fmt.Errorf("invalid expires: %d, expires must bigger than 0", expiredInSec)
}
@@ -913,7 +913,7 @@ func (bucket Bucket) SignURL(objectKey string, method HTTPMethod, expiredInSec i
return "", err
}
- return bucket.Client.Conn.signURL(method, bucket.BucketName, objectKey, expiration, params, headers), nil
+ return bucket.Client.Conn.signURL(method, bucket.BucketName, objectKey, expiration, params, headers)
}
// PutObjectWithURL uploads an object with the URL. If the object exists, it will be overwritten.
@@ -922,11 +922,11 @@ func (bucket Bucket) SignURL(objectKey string, method HTTPMethod, expiredInSec i
// signedURL signed URL.
// reader io.Reader the read instance for reading the data for the upload.
// options the options for uploading the data. The valid options are CacheControl, ContentDisposition, ContentEncoding,
-// Expires, ServerSideEncryption, ObjectACL and custom metadata. Check out the following link for details:
-// https://help.aliyun.com/document_detail/oss/api-reference/object/PutObject.html
//
-// error it's nil if no error, otherwise it's an error object.
+// Expires, ServerSideEncryption, ObjectACL and custom metadata. Check out the following link for details:
+// https://www.alibabacloud.com/help/en/object-storage-service/latest/putobject
//
+// error it's nil if no error, otherwise it's an error object.
func (bucket Bucket) PutObjectWithURL(signedURL string, reader io.Reader, options ...Option) error {
resp, err := bucket.DoPutObjectWithURL(signedURL, reader, options)
if err != nil {
@@ -945,7 +945,6 @@ func (bucket Bucket) PutObjectWithURL(signedURL string, reader io.Reader, option
// options options for uploading, same as the options in PutObject function.
//
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) PutObjectFromFileWithURL(signedURL, filePath string, options ...Option) error {
fd, err := os.Open(filePath)
if err != nil {
@@ -970,7 +969,6 @@ func (bucket Bucket) PutObjectFromFileWithURL(signedURL, filePath string, option
//
// Response the response object which contains the HTTP response.
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) DoPutObjectWithURL(signedURL string, reader io.Reader, options []Option) (*Response, error) {
listener := GetProgressListener(options)
@@ -996,12 +994,12 @@ func (bucket Bucket) DoPutObjectWithURL(signedURL string, reader io.Reader, opti
//
// signedURL the signed URL.
// options options for downloading the object. Valid options are IfModifiedSince, IfUnmodifiedSince, IfMatch,
-// IfNoneMatch, AcceptEncoding. For more information, check out the following link:
-// https://help.aliyun.com/document_detail/oss/api-reference/object/GetObject.html
+//
+// IfNoneMatch, AcceptEncoding. For more information, check out the following link:
+// https://www.alibabacloud.com/help/en/object-storage-service/latest/getobject
//
// io.ReadCloser the reader object for getting the data from response. It needs be closed after the usage. It's only valid when error is nil.
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) GetObjectWithURL(signedURL string, options ...Option) (io.ReadCloser, error) {
result, err := bucket.DoGetObjectWithURL(signedURL, options)
if err != nil {
@@ -1017,7 +1015,6 @@ func (bucket Bucket) GetObjectWithURL(signedURL string, options ...Option) (io.R
// options the options for downloading object. Check out the parameter options in function GetObject for the reference.
//
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) GetObjectToFileWithURL(signedURL, filePath string, options ...Option) error {
tempFilePath := filePath + TempFileSuffix
@@ -1068,7 +1065,6 @@ func (bucket Bucket) GetObjectToFileWithURL(signedURL, filePath string, options
//
// GetObjectResult the result object when the error is nil.
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) DoGetObjectWithURL(signedURL string, options []Option) (*GetObjectResult, error) {
params, _ := GetRawParams(options)
resp, err := bucket.doURL("GET", signedURL, params, options, nil, nil)
@@ -1098,18 +1094,15 @@ func (bucket Bucket) DoGetObjectWithURL(signedURL string, options []Option) (*Ge
return result, nil
}
-//
// ProcessObject apply process on the specified image file.
//
// The supported process includes resize, rotate, crop, watermark, format,
// udf, customized style, etc.
//
-//
// objectKey object key to process.
// process process string, such as "image/resize,w_100|sys/saveas,o_dGVzdC5qcGc,b_dGVzdA"
//
// error it's nil if no error, otherwise it's an error object.
-//
func (bucket Bucket) ProcessObject(objectKey string, process string, options ...Option) (ProcessObjectResult, error) {
var out ProcessObjectResult
params, _ := GetRawParams(options)
@@ -1126,14 +1119,38 @@ func (bucket Bucket) ProcessObject(objectKey string, process string, options ...
return out, err
}
+// AsyncProcessObject apply async process on the specified image file.
+//
+// The supported process includes resize, rotate, crop, watermark, format,
+// udf, customized style, etc.
//
+// objectKey object key to process.
+// asyncProcess process string, such as "image/resize,w_100|sys/saveas,o_dGVzdC5qcGc,b_dGVzdA"
+//
+// error it's nil if no error, otherwise it's an error object.
+func (bucket Bucket) AsyncProcessObject(objectKey string, asyncProcess string, options ...Option) (AsyncProcessObjectResult, error) {
+ var out AsyncProcessObjectResult
+ params, _ := GetRawParams(options)
+ params["x-oss-async-process"] = nil
+ processData := fmt.Sprintf("%v=%v", "x-oss-async-process", asyncProcess)
+ data := strings.NewReader(processData)
+
+ resp, err := bucket.do("POST", objectKey, params, nil, data, nil)
+ if err != nil {
+ return out, err
+ }
+ defer resp.Body.Close()
+
+ err = jsonUnmarshal(resp.Body, &out)
+ return out, err
+}
+
// PutObjectTagging add tagging to object
//
// objectKey object key to add tagging
// tagging tagging to be added
//
// error nil if success, otherwise error
-//
func (bucket Bucket) PutObjectTagging(objectKey string, tagging Tagging, options ...Option) error {
bs, err := xml.Marshal(tagging)
if err != nil {
@@ -1177,21 +1194,14 @@ func (bucket Bucket) GetObjectTagging(objectKey string, options ...Option) (GetO
return out, err
}
-//
// DeleteObjectTagging delete object taggging
//
// objectKey object key to delete tagging
//
// error nil if success, otherwise error
-//
func (bucket Bucket) DeleteObjectTagging(objectKey string, options ...Option) error {
params, _ := GetRawParams(options)
params["tagging"] = nil
-
- if objectKey == "" {
- return fmt.Errorf("invalid argument: object name is empty")
- }
-
resp, err := bucket.do("DELETE", objectKey, params, options, nil, nil)
if err != nil {
return err
@@ -1203,7 +1213,7 @@ func (bucket Bucket) DeleteObjectTagging(objectKey string, options ...Option) er
func (bucket Bucket) OptionsMethod(objectKey string, options ...Option) (http.Header, error) {
var out http.Header
- resp, err := bucket.do("OPTIONS", objectKey, nil, options, nil, nil)
+ resp, err := bucket.doInner("OPTIONS", objectKey, nil, options, nil, nil)
if err != nil {
return out, err
}
@@ -1215,11 +1225,11 @@ func (bucket Bucket) OptionsMethod(objectKey string, options ...Option) (http.He
// public
func (bucket Bucket) Do(method, objectName string, params map[string]interface{}, options []Option,
data io.Reader, listener ProgressListener) (*Response, error) {
- return bucket.do(method, objectName, params, options, data, listener)
+ return bucket.doInner(method, objectName, params, options, data, listener)
}
// Private
-func (bucket Bucket) do(method, objectName string, params map[string]interface{}, options []Option,
+func (bucket Bucket) doInner(method, objectName string, params map[string]interface{}, options []Option,
data io.Reader, listener ProgressListener) (*Response, error) {
headers := make(map[string]string)
err := handleOptions(headers, options)
@@ -1232,34 +1242,56 @@ func (bucket Bucket) do(method, objectName string, params map[string]interface{}
return nil, err
}
- resp, err := bucket.Client.Conn.Do(method, bucket.BucketName, objectName,
+ ctxArg, _ := FindOption(options, contextArg, nil)
+ ctx, _ := ctxArg.(context.Context)
+
+ resp, err := bucket.Client.Conn.DoWithContext(ctx, method, bucket.BucketName, objectName,
params, headers, data, 0, listener)
// get response header
respHeader, _ := FindOption(options, responseHeader, nil)
if respHeader != nil && resp != nil {
pRespHeader := respHeader.(*http.Header)
- *pRespHeader = resp.Headers
+ if resp != nil {
+ *pRespHeader = resp.Headers
+ }
}
return resp, err
}
+// Private check object name before bucket.do
+func (bucket Bucket) do(method, objectName string, params map[string]interface{}, options []Option,
+ data io.Reader, listener ProgressListener) (*Response, error) {
+ err := CheckObjectName(objectName)
+ if err != nil {
+ return nil, err
+ }
+ resp, err := bucket.doInner(method, objectName, params, options, data, listener)
+ return resp, err
+}
+
func (bucket Bucket) doURL(method HTTPMethod, signedURL string, params map[string]interface{}, options []Option,
data io.Reader, listener ProgressListener) (*Response, error) {
+
headers := make(map[string]string)
err := handleOptions(headers, options)
if err != nil {
return nil, err
}
- resp, err := bucket.Client.Conn.DoURL(method, signedURL, headers, data, 0, listener)
+ ctxArg, _ := FindOption(options, contextArg, nil)
+ ctx, _ := ctxArg.(context.Context)
+
+ resp, err := bucket.Client.Conn.DoURLWithContext(ctx, method, signedURL, headers, data, 0, listener)
// get response header
respHeader, _ := FindOption(options, responseHeader, nil)
if respHeader != nil {
pRespHeader := respHeader.(*http.Header)
- *pRespHeader = resp.Headers
+ if resp != nil {
+ *pRespHeader = resp.Headers
+ }
}
return resp, err
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/client.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/client.go
index aacf3e7f7..5910bb3bf 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/client.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/client.go
@@ -49,10 +49,6 @@ func New(endpoint, accessKeyID, accessKeySecret string, options ...ClientOption)
// URL parse
url := &urlMaker{}
- err := url.Init(config.Endpoint, config.IsCname, config.IsUseProxy)
- if err != nil {
- return nil, err
- }
// HTTP connect
conn := &Conn{config: config, url: url}
@@ -68,7 +64,12 @@ func New(endpoint, accessKeyID, accessKeySecret string, options ...ClientOption)
option(client)
}
- if config.AuthVersion != AuthV1 && config.AuthVersion != AuthV2 {
+ err := url.InitExt(config.Endpoint, config.IsCname, config.IsUseProxy, config.IsPathStyle)
+ if err != nil {
+ return nil, err
+ }
+
+ if config.AuthVersion != AuthV1 && config.AuthVersion != AuthV2 && config.AuthVersion != AuthV4 {
return nil, fmt.Errorf("Init client Error, invalid Auth version: %v", config.AuthVersion)
}
@@ -78,6 +79,27 @@ func New(endpoint, accessKeyID, accessKeySecret string, options ...ClientOption)
return client, err
}
+// SetRegion set region for client
+//
+// region the region, such as cn-hangzhou
+func (client *Client) SetRegion(region string) {
+ client.Config.Region = region
+}
+
+// SetCloudBoxId set CloudBoxId for client
+//
+// cloudBoxId the id of cloudBox
+func (client *Client) SetCloudBoxId(cloudBoxId string) {
+ client.Config.CloudBoxId = cloudBoxId
+}
+
+// SetProduct set Product type for client
+//
+// Product product type
+func (client *Client) SetProduct(product string) {
+ client.Config.Product = product
+}
+
// Bucket gets the bucket instance.
//
// bucketName the bucket name.
@@ -148,6 +170,24 @@ func (client Client) CreateBucket(bucketName string, options ...Option) error {
return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
}
+// create bucket xml
+func (client Client) CreateBucketXml(bucketName string, xmlBody string, options ...Option) error {
+ buffer := new(bytes.Buffer)
+ buffer.Write([]byte(xmlBody))
+ contentType := http.DetectContentType(buffer.Bytes())
+ headers := map[string]string{}
+ headers[HTTPHeaderContentType] = contentType
+
+ params := map[string]interface{}{}
+ resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
+ if err != nil {
+ return err
+ }
+
+ defer resp.Body.Close()
+ return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
+}
+
// ListBuckets lists buckets of the current account under the given endpoint, with optional filters.
//
// options specifies the filters such as Prefix, Marker and MaxKeys. Prefix is the bucket name's prefix filter.
@@ -176,6 +216,36 @@ func (client Client) ListBuckets(options ...Option) (ListBucketsResult, error) {
return out, err
}
+// ListCloudBoxes lists cloud boxes of the current account under the given endpoint, with optional filters.
+//
+// options specifies the filters such as Prefix, Marker and MaxKeys. Prefix is the bucket name's prefix filter.
+// And marker makes sure the returned buckets' name are greater than it in lexicographic order.
+// Maxkeys limits the max keys to return, and by default it's 100 and up to 1000.
+// For the common usage scenario, please check out list_bucket.go in the sample.
+// ListBucketsResponse the response object if error is nil.
+//
+// error it's nil if no error, otherwise it's an error object.
+//
+func (client Client) ListCloudBoxes(options ...Option) (ListCloudBoxResult, error) {
+ var out ListCloudBoxResult
+
+ params, err := GetRawParams(options)
+ if err != nil {
+ return out, err
+ }
+
+ params["cloudboxes"] = nil
+
+ resp, err := client.do("GET", "", params, nil, nil, options...)
+ if err != nil {
+ return out, err
+ }
+ defer resp.Body.Close()
+
+ err = xmlUnmarshal(resp.Body, &out)
+ return out, err
+}
+
// IsBucketExist checks if the bucket exists
//
// bucketName the bucket name.
@@ -215,17 +285,17 @@ func (client Client) DeleteBucket(bucketName string, options ...Option) error {
// GetBucketLocation gets the bucket location.
//
// Checks out the following link for more information :
-// https://help.aliyun.com/document_detail/oss/user_guide/oss_concept/endpoint.html
+// https://www.alibabacloud.com/help/en/object-storage-service/latest/getbucketlocation
//
// bucketName the bucket name
//
// string bucket's datacenter location
// error it's nil if no error, otherwise it's an error object.
//
-func (client Client) GetBucketLocation(bucketName string) (string, error) {
+func (client Client) GetBucketLocation(bucketName string, options ...Option) (string, error) {
params := map[string]interface{}{}
params["location"] = nil
- resp, err := client.do("GET", bucketName, params, nil, nil)
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
if err != nil {
return "", err
}
@@ -243,11 +313,11 @@ func (client Client) GetBucketLocation(bucketName string) (string, error) {
//
// error it's nil if no error, otherwise it's an error object.
//
-func (client Client) SetBucketACL(bucketName string, bucketACL ACLType) error {
+func (client Client) SetBucketACL(bucketName string, bucketACL ACLType, options ...Option) error {
headers := map[string]string{HTTPHeaderOssACL: string(bucketACL)}
params := map[string]interface{}{}
params["acl"] = nil
- resp, err := client.do("PUT", bucketName, params, headers, nil)
+ resp, err := client.do("PUT", bucketName, params, headers, nil, options...)
if err != nil {
return err
}
@@ -262,11 +332,11 @@ func (client Client) SetBucketACL(bucketName string, bucketACL ACLType) error {
// GetBucketAclResponse the result object, and it's only valid when error is nil.
// error it's nil if no error, otherwise it's an error object.
//
-func (client Client) GetBucketACL(bucketName string) (GetBucketACLResult, error) {
+func (client Client) GetBucketACL(bucketName string, options ...Option) (GetBucketACLResult, error) {
var out GetBucketACLResult
params := map[string]interface{}{}
params["acl"] = nil
- resp, err := client.do("GET", bucketName, params, nil, nil)
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
if err != nil {
return out, err
}
@@ -279,7 +349,7 @@ func (client Client) GetBucketACL(bucketName string) (GetBucketACLResult, error)
// SetBucketLifecycle sets the bucket's lifecycle.
//
// For more information, checks out following link:
-// https://help.aliyun.com/document_detail/oss/user_guide/manage_object/object_lifecycle.html
+// https://www.alibabacloud.com/help/en/object-storage-service/latest/putbucketlifecycle
//
// bucketName the bucket name.
// rules the lifecycle rules. There're two kind of rules: absolute time expiration and relative time expiration in days and day/month/year respectively.
@@ -287,7 +357,7 @@ func (client Client) GetBucketACL(bucketName string) (GetBucketACLResult, error)
//
// error it's nil if no error, otherwise it's an error object.
//
-func (client Client) SetBucketLifecycle(bucketName string, rules []LifecycleRule) error {
+func (client Client) SetBucketLifecycle(bucketName string, rules []LifecycleRule, options ...Option) error {
err := verifyLifecycleRules(rules)
if err != nil {
return err
@@ -306,7 +376,26 @@ func (client Client) SetBucketLifecycle(bucketName string, rules []LifecycleRule
params := map[string]interface{}{}
params["lifecycle"] = nil
- resp, err := client.do("PUT", bucketName, params, headers, buffer)
+ resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
+}
+
+// SetBucketLifecycleXml sets the bucket's lifecycle rule from xml config
+func (client Client) SetBucketLifecycleXml(bucketName string, xmlBody string, options ...Option) error {
+ buffer := new(bytes.Buffer)
+ buffer.Write([]byte(xmlBody))
+
+ contentType := http.DetectContentType(buffer.Bytes())
+ headers := map[string]string{}
+ headers[HTTPHeaderContentType] = contentType
+
+ params := map[string]interface{}{}
+ params["lifecycle"] = nil
+ resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
if err != nil {
return err
}
@@ -321,10 +410,10 @@ func (client Client) SetBucketLifecycle(bucketName string, rules []LifecycleRule
//
// error it's nil if no error, otherwise it's an error object.
//
-func (client Client) DeleteBucketLifecycle(bucketName string) error {
+func (client Client) DeleteBucketLifecycle(bucketName string, options ...Option) error {
params := map[string]interface{}{}
params["lifecycle"] = nil
- resp, err := client.do("DELETE", bucketName, params, nil, nil)
+ resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
if err != nil {
return err
}
@@ -339,11 +428,11 @@ func (client Client) DeleteBucketLifecycle(bucketName string) error {
// GetBucketLifecycleResponse the result object upon successful request. It's only valid when error is nil.
// error it's nil if no error, otherwise it's an error object.
//
-func (client Client) GetBucketLifecycle(bucketName string) (GetBucketLifecycleResult, error) {
+func (client Client) GetBucketLifecycle(bucketName string, options ...Option) (GetBucketLifecycleResult, error) {
var out GetBucketLifecycleResult
params := map[string]interface{}{}
params["lifecycle"] = nil
- resp, err := client.do("GET", bucketName, params, nil, nil)
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
if err != nil {
return out, err
}
@@ -361,29 +450,43 @@ func (client Client) GetBucketLifecycle(bucketName string) (GetBucketLifecycleRe
return out, err
}
+func (client Client) GetBucketLifecycleXml(bucketName string, options ...Option) (string, error) {
+ params := map[string]interface{}{}
+ params["lifecycle"] = nil
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
+ if err != nil {
+ return "", err
+ }
+ defer resp.Body.Close()
+
+ body, err := ioutil.ReadAll(resp.Body)
+ out := string(body)
+ return out, err
+}
+
// SetBucketReferer sets the bucket's referer whitelist and the flag if allowing empty referrer.
//
// To avoid stealing link on OSS data, OSS supports the HTTP referrer header. A whitelist referrer could be set either by API or web console, as well as
-// the allowing empty referrer flag. Note that this applies to requests from webbrowser only.
+// the allowing empty referrer flag. Note that this applies to requests from web browser only.
// For example, for a bucket os-example and its referrer http://www.aliyun.com, all requests from this URL could access the bucket.
// For more information, please check out this link :
-// https://help.aliyun.com/document_detail/oss/user_guide/security_management/referer.html
+// https://www.alibabacloud.com/help/en/object-storage-service/latest/putbucketreferer
//
// bucketName the bucket name.
-// referers the referrer white list. A bucket could have a referrer list and each referrer supports one '*' and multiple '?' as wildcards.
+// referrers the referrer white list. A bucket could have a referrer list and each referrer supports one '*' and multiple '?' as wildcards.
// The sample could be found in sample/bucket_referer.go
// allowEmptyReferer the flag of allowing empty referrer. By default it's true.
//
// error it's nil if no error, otherwise it's an error object.
//
-func (client Client) SetBucketReferer(bucketName string, referers []string, allowEmptyReferer bool) error {
+func (client Client) SetBucketReferer(bucketName string, referrers []string, allowEmptyReferer bool, options ...Option) error {
rxml := RefererXML{}
rxml.AllowEmptyReferer = allowEmptyReferer
- if referers == nil {
+ if referrers == nil {
rxml.RefererList = append(rxml.RefererList, "")
} else {
- for _, referer := range referers {
- rxml.RefererList = append(rxml.RefererList, referer)
+ for _, referrer := range referrers {
+ rxml.RefererList = append(rxml.RefererList, referrer)
}
}
@@ -391,16 +494,39 @@ func (client Client) SetBucketReferer(bucketName string, referers []string, allo
if err != nil {
return err
}
- buffer := new(bytes.Buffer)
- buffer.Write(bs)
+ return client.PutBucketRefererXml(bucketName, string(bs), options...)
+}
+
+// SetBucketRefererV2 gets the bucket's referer white list.
+//
+// setBucketReferer SetBucketReferer bucket referer config in struct format.
+//
+// GetBucketRefererResponse the result object upon successful request. It's only valid when error is nil.
+// error it's nil if no error, otherwise it's an error object.
+//
+func (client Client) SetBucketRefererV2(bucketName string, setBucketReferer RefererXML, options ...Option) error {
+ bs, err := xml.Marshal(setBucketReferer)
+ if err != nil {
+ return err
+ }
+ return client.PutBucketRefererXml(bucketName, string(bs), options...)
+}
+
+// PutBucketRefererXml set bucket's style
+// bucketName the bucket name.
+// xmlData the style in xml format
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) PutBucketRefererXml(bucketName, xmlData string, options ...Option) error {
+ buffer := new(bytes.Buffer)
+ buffer.Write([]byte(xmlData))
contentType := http.DetectContentType(buffer.Bytes())
headers := map[string]string{}
headers[HTTPHeaderContentType] = contentType
params := map[string]interface{}{}
params["referer"] = nil
- resp, err := client.do("PUT", bucketName, params, headers, buffer)
+ resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
if err != nil {
return err
}
@@ -409,31 +535,40 @@ func (client Client) SetBucketReferer(bucketName string, referers []string, allo
}
// GetBucketReferer gets the bucket's referrer white list.
-//
// bucketName the bucket name.
-//
-// GetBucketRefererResponse the result object upon successful request. It's only valid when error is nil.
+// GetBucketRefererResult the result object upon successful request. It's only valid when error is nil.
// error it's nil if no error, otherwise it's an error object.
-//
-func (client Client) GetBucketReferer(bucketName string) (GetBucketRefererResult, error) {
+func (client Client) GetBucketReferer(bucketName string, options ...Option) (GetBucketRefererResult, error) {
var out GetBucketRefererResult
+ body, err := client.GetBucketRefererXml(bucketName, options...)
+ if err != nil {
+ return out, err
+ }
+ err = xmlUnmarshal(strings.NewReader(body), &out)
+ return out, err
+}
+
+// GetBucketRefererXml gets the bucket's referrer white list.
+// bucketName the bucket name.
+// GetBucketRefererResponse the bucket referer config result in xml format.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) GetBucketRefererXml(bucketName string, options ...Option) (string, error) {
params := map[string]interface{}{}
params["referer"] = nil
- resp, err := client.do("GET", bucketName, params, nil, nil)
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
if err != nil {
- return out, err
+ return "", err
}
defer resp.Body.Close()
-
- err = xmlUnmarshal(resp.Body, &out)
- return out, err
+ body, err := ioutil.ReadAll(resp.Body)
+ return string(body), err
}
// SetBucketLogging sets the bucket logging settings.
//
// OSS could automatically store the access log. Only the bucket owner could enable the logging.
// Once enabled, OSS would save all the access log into hourly log files in a specified bucket.
-// For more information, please check out https://help.aliyun.com/document_detail/oss/user_guide/security_management/logging.html
+// For more information, please check out https://www.alibabacloud.com/help/en/object-storage-service/latest/putbucketlogging
//
// bucketName bucket name to enable the log.
// targetBucket the target bucket name to store the log files.
@@ -442,7 +577,7 @@ func (client Client) GetBucketReferer(bucketName string) (GetBucketRefererResult
// error it's nil if no error, otherwise it's an error object.
//
func (client Client) SetBucketLogging(bucketName, targetBucket, targetPrefix string,
- isEnable bool) error {
+ isEnable bool, options ...Option) error {
var err error
var bs []byte
if isEnable {
@@ -468,7 +603,7 @@ func (client Client) SetBucketLogging(bucketName, targetBucket, targetPrefix str
params := map[string]interface{}{}
params["logging"] = nil
- resp, err := client.do("PUT", bucketName, params, headers, buffer)
+ resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
if err != nil {
return err
}
@@ -482,10 +617,10 @@ func (client Client) SetBucketLogging(bucketName, targetBucket, targetPrefix str
//
// error it's nil if no error, otherwise it's an error object.
//
-func (client Client) DeleteBucketLogging(bucketName string) error {
+func (client Client) DeleteBucketLogging(bucketName string, options ...Option) error {
params := map[string]interface{}{}
params["logging"] = nil
- resp, err := client.do("DELETE", bucketName, params, nil, nil)
+ resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
if err != nil {
return err
}
@@ -500,11 +635,11 @@ func (client Client) DeleteBucketLogging(bucketName string) error {
//
// error it's nil if no error, otherwise it's an error object.
//
-func (client Client) GetBucketLogging(bucketName string) (GetBucketLoggingResult, error) {
+func (client Client) GetBucketLogging(bucketName string, options ...Option) (GetBucketLoggingResult, error) {
var out GetBucketLoggingResult
params := map[string]interface{}{}
params["logging"] = nil
- resp, err := client.do("GET", bucketName, params, nil, nil)
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
if err != nil {
return out, err
}
@@ -517,7 +652,7 @@ func (client Client) GetBucketLogging(bucketName string) (GetBucketLoggingResult
// SetBucketWebsite sets the bucket's static website's index and error page.
//
// OSS supports static web site hosting for the bucket data. When the bucket is enabled with that, you can access the file in the bucket like the way to access a static website.
-// For more information, please check out: https://help.aliyun.com/document_detail/oss/user_guide/static_host_website.html
+// For more information, please check out: https://www.alibabacloud.com/help/en/object-storage-service/latest/putbucketwebsite
//
// bucketName the bucket name to enable static web site.
// indexDocument index page.
@@ -525,7 +660,7 @@ func (client Client) GetBucketLogging(bucketName string) (GetBucketLoggingResult
//
// error it's nil if no error, otherwise it's an error object.
//
-func (client Client) SetBucketWebsite(bucketName, indexDocument, errorDocument string) error {
+func (client Client) SetBucketWebsite(bucketName, indexDocument, errorDocument string, options ...Option) error {
wxml := WebsiteXML{}
wxml.IndexDocument.Suffix = indexDocument
wxml.ErrorDocument.Key = errorDocument
@@ -543,7 +678,7 @@ func (client Client) SetBucketWebsite(bucketName, indexDocument, errorDocument s
params := map[string]interface{}{}
params["website"] = nil
- resp, err := client.do("PUT", bucketName, params, headers, buffer)
+ resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
if err != nil {
return err
}
@@ -554,7 +689,7 @@ func (client Client) SetBucketWebsite(bucketName, indexDocument, errorDocument s
// SetBucketWebsiteDetail sets the bucket's static website's detail
//
// OSS supports static web site hosting for the bucket data. When the bucket is enabled with that, you can access the file in the bucket like the way to access a static website.
-// For more information, please check out: https://help.aliyun.com/document_detail/oss/user_guide/static_host_website.html
+// For more information, please check out: https://www.alibabacloud.com/help/en/object-storage-service/latest/putbucketwebsite
//
// bucketName the bucket name to enable static web site.
//
@@ -587,7 +722,7 @@ func (client Client) SetBucketWebsiteDetail(bucketName string, wxml WebsiteXML,
// SetBucketWebsiteXml sets the bucket's static website's rule
//
// OSS supports static web site hosting for the bucket data. When the bucket is enabled with that, you can access the file in the bucket like the way to access a static website.
-// For more information, please check out: https://help.aliyun.com/document_detail/oss/user_guide/static_host_website.html
+// For more information, please check out: https://www.alibabacloud.com/help/en/object-storage-service/latest/putbucketwebsite
//
// bucketName the bucket name to enable static web site.
//
@@ -619,10 +754,10 @@ func (client Client) SetBucketWebsiteXml(bucketName string, webXml string, optio
//
// error it's nil if no error, otherwise it's an error object.
//
-func (client Client) DeleteBucketWebsite(bucketName string) error {
+func (client Client) DeleteBucketWebsite(bucketName string, options ...Option) error {
params := map[string]interface{}{}
params["website"] = nil
- resp, err := client.do("DELETE", bucketName, params, nil, nil)
+ resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
if err != nil {
return err
}
@@ -630,6 +765,110 @@ func (client Client) DeleteBucketWebsite(bucketName string) error {
return CheckRespCode(resp.StatusCode, []int{http.StatusNoContent})
}
+// OpenMetaQuery Enables the metadata management feature for a bucket.
+//
+// bucketName the bucket name.
+//
+// error it's nil if no error, otherwise it's an error object.
+//
+func (client Client) OpenMetaQuery(bucketName string, options ...Option) error {
+ params := map[string]interface{}{}
+ params["metaQuery"] = nil
+ params["comp"] = "add"
+ resp, err := client.do("POST", bucketName, params, nil, nil, options...)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
+}
+
+// GetMetaQueryStatus Queries the information about the metadata index library of a bucket.
+//
+// bucketName the bucket name
+//
+// GetMetaQueryStatusResult the result object upon successful request. It's only valid when error is nil.
+// error it's nil if no error, otherwise it's an error object.
+//
+func (client Client) GetMetaQueryStatus(bucketName string, options ...Option) (GetMetaQueryStatusResult, error) {
+ var out GetMetaQueryStatusResult
+ params := map[string]interface{}{}
+ params["metaQuery"] = nil
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
+ if err != nil {
+ return out, err
+ }
+ defer resp.Body.Close()
+ err = xmlUnmarshal(resp.Body, &out)
+ return out, err
+}
+
+// DoMetaQuery Queries the objects that meet specified conditions and lists the information about objects based on specified fields and sorting methods.
+//
+// bucketName the bucket name
+//
+// metaQuery the option of query
+//
+// DoMetaQueryResult the result object upon successful request. It's only valid when error is nil.
+// error it's nil if no error, otherwise it's an error object.
+//
+func (client Client) DoMetaQuery(bucketName string, metaQuery MetaQuery, options ...Option) (DoMetaQueryResult, error) {
+ var out DoMetaQueryResult
+ bs, err := xml.Marshal(metaQuery)
+ if err != nil {
+ return out, err
+ }
+ out, err = client.DoMetaQueryXml(bucketName, string(bs), options...)
+ return out, err
+}
+
+// DoMetaQueryXml Queries the objects that meet specified conditions and lists the information about objects based on specified fields and sorting methods.
+//
+// bucketName the bucket name
+//
+// metaQuery the option of query
+//
+// DoMetaQueryResult the result object upon successful request. It's only valid when error is nil.
+// error it's nil if no error, otherwise it's an error object.
+//
+func (client Client) DoMetaQueryXml(bucketName string, metaQueryXml string, options ...Option) (DoMetaQueryResult, error) {
+ var out DoMetaQueryResult
+ buffer := new(bytes.Buffer)
+ buffer.Write([]byte(metaQueryXml))
+ contentType := http.DetectContentType(buffer.Bytes())
+ headers := map[string]string{}
+ headers[HTTPHeaderContentType] = contentType
+
+ params := map[string]interface{}{}
+ params["metaQuery"] = nil
+ params["comp"] = "query"
+ resp, err := client.do("POST", bucketName, params, headers, buffer, options...)
+ if err != nil {
+ return out, err
+ }
+ defer resp.Body.Close()
+ err = xmlUnmarshal(resp.Body, &out)
+ return out, err
+}
+
+// CloseMetaQuery Disables the metadata management feature for a bucket.
+//
+// bucketName the bucket name.
+//
+// error it's nil if no error, otherwise it's an error object.
+//
+func (client Client) CloseMetaQuery(bucketName string, options ...Option) error {
+ params := map[string]interface{}{}
+ params["metaQuery"] = nil
+ params["comp"] = "delete"
+ resp, err := client.do("POST", bucketName, params, nil, nil, options...)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
+}
+
// GetBucketWebsite gets the bucket's default page (index page) and the error page.
//
// bucketName the bucket name
@@ -637,11 +876,11 @@ func (client Client) DeleteBucketWebsite(bucketName string) error {
// GetBucketWebsiteResponse the result object upon successful request. It's only valid when error is nil.
// error it's nil if no error, otherwise it's an error object.
//
-func (client Client) GetBucketWebsite(bucketName string) (GetBucketWebsiteResult, error) {
+func (client Client) GetBucketWebsite(bucketName string, options ...Option) (GetBucketWebsiteResult, error) {
var out GetBucketWebsiteResult
params := map[string]interface{}{}
params["website"] = nil
- resp, err := client.do("GET", bucketName, params, nil, nil)
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
if err != nil {
return out, err
}
@@ -658,10 +897,10 @@ func (client Client) GetBucketWebsite(bucketName string) (GetBucketWebsiteResult
// string the bucket's xml config, It's only valid when error is nil.
// error it's nil if no error, otherwise it's an error object.
//
-func (client Client) GetBucketWebsiteXml(bucketName string) (string, error) {
+func (client Client) GetBucketWebsiteXml(bucketName string, options ...Option) (string, error) {
params := map[string]interface{}{}
params["website"] = nil
- resp, err := client.do("GET", bucketName, params, nil, nil)
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
if err != nil {
return "", err
}
@@ -682,7 +921,7 @@ func (client Client) GetBucketWebsiteXml(bucketName string) (string, error) {
//
// error it's nil if no error, otherwise it's an error object.
//
-func (client Client) SetBucketCORS(bucketName string, corsRules []CORSRule) error {
+func (client Client) SetBucketCORS(bucketName string, corsRules []CORSRule, options ...Option) error {
corsxml := CORSXML{}
for _, v := range corsRules {
cr := CORSRule{}
@@ -707,7 +946,40 @@ func (client Client) SetBucketCORS(bucketName string, corsRules []CORSRule) erro
params := map[string]interface{}{}
params["cors"] = nil
- resp, err := client.do("PUT", bucketName, params, headers, buffer)
+ resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
+}
+
+// SetBucketCORSV2 sets the bucket's CORS rules
+//
+// bucketName the bucket name
+// putBucketCORS the CORS rules to set.
+//
+// error it's nil if no error, otherwise it's an error object.
+//
+func (client Client) SetBucketCORSV2(bucketName string, putBucketCORS PutBucketCORS, options ...Option) error {
+ bs, err := xml.Marshal(putBucketCORS)
+ if err != nil {
+ return err
+ }
+ err = client.SetBucketCORSXml(bucketName, string(bs), options...)
+ return err
+}
+
+func (client Client) SetBucketCORSXml(bucketName string, xmlBody string, options ...Option) error {
+ buffer := new(bytes.Buffer)
+ buffer.Write([]byte(xmlBody))
+ contentType := http.DetectContentType(buffer.Bytes())
+ headers := map[string]string{}
+ headers[HTTPHeaderContentType] = contentType
+
+ params := map[string]interface{}{}
+ params["cors"] = nil
+ resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
if err != nil {
return err
}
@@ -721,10 +993,10 @@ func (client Client) SetBucketCORS(bucketName string, corsRules []CORSRule) erro
//
// error it's nil if no error, otherwise it's an error object.
//
-func (client Client) DeleteBucketCORS(bucketName string) error {
+func (client Client) DeleteBucketCORS(bucketName string, options ...Option) error {
params := map[string]interface{}{}
params["cors"] = nil
- resp, err := client.do("DELETE", bucketName, params, nil, nil)
+ resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
if err != nil {
return err
}
@@ -739,11 +1011,11 @@ func (client Client) DeleteBucketCORS(bucketName string) error {
//
// error it's nil if no error, otherwise it's an error object.
//
-func (client Client) GetBucketCORS(bucketName string) (GetBucketCORSResult, error) {
+func (client Client) GetBucketCORS(bucketName string, options ...Option) (GetBucketCORSResult, error) {
var out GetBucketCORSResult
params := map[string]interface{}{}
params["cors"] = nil
- resp, err := client.do("GET", bucketName, params, nil, nil)
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
if err != nil {
return out, err
}
@@ -753,6 +1025,20 @@ func (client Client) GetBucketCORS(bucketName string) (GetBucketCORSResult, erro
return out, err
}
+func (client Client) GetBucketCORSXml(bucketName string, options ...Option) (string, error) {
+ params := map[string]interface{}{}
+ params["cors"] = nil
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
+ if err != nil {
+ return "", err
+ }
+ defer resp.Body.Close()
+
+ body, err := ioutil.ReadAll(resp.Body)
+ out := string(body)
+ return out, err
+}
+
// GetBucketInfo gets the bucket information.
//
// bucketName the bucket name.
@@ -954,8 +1240,14 @@ func (client Client) GetBucketTagging(bucketName string, options ...Option) (Get
// error nil if success, otherwise error
//
func (client Client) DeleteBucketTagging(bucketName string, options ...Option) error {
+ key, _ := FindOption(options, "tagging", nil)
params := map[string]interface{}{}
- params["tagging"] = nil
+ if key == nil {
+ params["tagging"] = nil
+ } else {
+ params["tagging"] = key.(string)
+ }
+
resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
if err != nil {
return err
@@ -967,11 +1259,11 @@ func (client Client) DeleteBucketTagging(bucketName string, options ...Option) e
// GetBucketStat get bucket stat
// bucketName the bucket name.
// error it's nil if no error, otherwise it's an error object.
-func (client Client) GetBucketStat(bucketName string) (GetBucketStatResult, error) {
+func (client Client) GetBucketStat(bucketName string, options ...Option) (GetBucketStatResult, error) {
var out GetBucketStatResult
params := map[string]interface{}{}
params["stat"] = nil
- resp, err := client.do("GET", bucketName, params, nil, nil)
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
if err != nil {
return out, err
}
@@ -1221,7 +1513,7 @@ func (client Client) DeleteBucketQosInfo(bucketName string, options ...Option) e
//
// Set the Bucket inventory.
//
-// bucketName tht bucket name.
+// bucketName the bucket name.
//
// inventoryConfig the inventory configuration.
//
@@ -1257,6 +1549,47 @@ func (client Client) SetBucketInventory(bucketName string, inventoryConfig Inven
return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
}
+// SetBucketInventoryXml API operation for Object Storage Service
+//
+// Set the Bucket inventory
+//
+// bucketName the bucket name.
+//
+// xmlBody the inventory configuration.
+//
+// error it's nil if no error, otherwise it's an error.
+//
+func (client Client) SetBucketInventoryXml(bucketName string, xmlBody string, options ...Option) error {
+ var inventoryConfig InventoryConfiguration
+ err := xml.Unmarshal([]byte(xmlBody), &inventoryConfig)
+ if err != nil {
+ return err
+ }
+
+ if inventoryConfig.Id == "" {
+ return fmt.Errorf("inventory id is empty in xml")
+ }
+
+ params := map[string]interface{}{}
+ params["inventoryId"] = inventoryConfig.Id
+ params["inventory"] = nil
+
+ buffer := new(bytes.Buffer)
+ buffer.Write([]byte(xmlBody))
+
+ contentType := http.DetectContentType(buffer.Bytes())
+ headers := make(map[string]string)
+ headers[HTTPHeaderContentType] = contentType
+
+ resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
+ if err != nil {
+ return err
+ }
+
+ defer resp.Body.Close()
+ return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
+}
+
// GetBucketInventory API operation for Object Storage Service
//
// Get the Bucket inventory.
@@ -1285,6 +1618,33 @@ func (client Client) GetBucketInventory(bucketName string, strInventoryId string
return out, err
}
+// GetBucketInventoryXml API operation for Object Storage Service
+//
+// Get the Bucket inventory.
+//
+// bucketName tht bucket name.
+//
+// strInventoryId the inventory id.
+//
+// InventoryConfiguration the inventory configuration.
+//
+// error it's nil if no error, otherwise it's an error.
+//
+func (client Client) GetBucketInventoryXml(bucketName string, strInventoryId string, options ...Option) (string, error) {
+ params := map[string]interface{}{}
+ params["inventory"] = nil
+ params["inventoryId"] = strInventoryId
+
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
+ if err != nil {
+ return "", err
+ }
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ out := string(body)
+ return out, err
+}
+
// ListBucketInventory API operation for Object Storage Service
//
// List the Bucket inventory.
@@ -1317,6 +1677,37 @@ func (client Client) ListBucketInventory(bucketName, continuationToken string, o
return out, err
}
+// ListBucketInventoryXml API operation for Object Storage Service
+//
+// List the Bucket inventory.
+//
+// bucketName tht bucket name.
+//
+// continuationToken the users token.
+//
+// ListInventoryConfigurationsResult list all inventory configuration by .
+//
+// error it's nil if no error, otherwise it's an error.
+//
+func (client Client) ListBucketInventoryXml(bucketName, continuationToken string, options ...Option) (string, error) {
+ params := map[string]interface{}{}
+ params["inventory"] = nil
+ if continuationToken == "" {
+ params["continuation-token"] = nil
+ } else {
+ params["continuation-token"] = continuationToken
+ }
+
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
+ if err != nil {
+ return "", err
+ }
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ out := string(body)
+ return out, err
+}
+
// DeleteBucketInventory API operation for Object Storage Service.
//
// Delete Bucket inventory information.
@@ -1563,7 +1954,7 @@ func (client Client) GetBucketTransferAcc(bucketName string, options ...Option)
var out TransferAccConfiguration
params := map[string]interface{}{}
params["transferAcceleration"] = nil
- resp, err := client.do("GET", bucketName, params, nil, nil)
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
if err != nil {
return out, err
}
@@ -1580,7 +1971,7 @@ func (client Client) GetBucketTransferAcc(bucketName string, options ...Option)
func (client Client) DeleteBucketTransferAcc(bucketName string, options ...Option) error {
params := map[string]interface{}{}
params["transferAcceleration"] = nil
- resp, err := client.do("DELETE", bucketName, params, nil, nil)
+ resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
if err != nil {
return err
}
@@ -1588,135 +1979,853 @@ func (client Client) DeleteBucketTransferAcc(bucketName string, options ...Optio
return CheckRespCode(resp.StatusCode, []int{http.StatusNoContent})
}
-// LimitUploadSpeed set upload bandwidth limit speed,default is 0,unlimited
-// upSpeed KB/s, 0 is unlimited,default is 0
-// error it's nil if success, otherwise failure
-func (client Client) LimitUploadSpeed(upSpeed int) error {
- if client.Config == nil {
- return fmt.Errorf("client config is nil")
- }
- return client.Config.LimitUploadSpeed(upSpeed)
-}
-
-// UseCname sets the flag of using CName. By default it's false.
-//
-// isUseCname true: the endpoint has the CName, false: the endpoint does not have cname. Default is false.
+// PutBucketReplication put bucket replication configuration
+// bucketName the bucket name.
+// xmlBody the replication configuration.
+// error it's nil if no error, otherwise it's an error object.
//
-func UseCname(isUseCname bool) ClientOption {
- return func(client *Client) {
- client.Config.IsCname = isUseCname
- client.Conn.url.Init(client.Config.Endpoint, client.Config.IsCname, client.Config.IsUseProxy)
+func (client Client) PutBucketReplication(bucketName string, xmlBody string, options ...Option) error {
+ buffer := new(bytes.Buffer)
+ buffer.Write([]byte(xmlBody))
+
+ contentType := http.DetectContentType(buffer.Bytes())
+ headers := map[string]string{}
+ headers[HTTPHeaderContentType] = contentType
+
+ params := map[string]interface{}{}
+ params["replication"] = nil
+ params["comp"] = "add"
+ resp, err := client.do("POST", bucketName, params, headers, buffer, options...)
+ if err != nil {
+ return err
}
+ defer resp.Body.Close()
+ return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
}
-// Timeout sets the HTTP timeout in seconds.
-//
-// connectTimeoutSec HTTP timeout in seconds. Default is 10 seconds. 0 means infinite (not recommended)
-// readWriteTimeout HTTP read or write's timeout in seconds. Default is 20 seconds. 0 means infinite.
+// PutBucketRTC put bucket replication rtc
+// bucketName the bucket name.
+// rtc the bucket rtc config.
+// error it's nil if no error, otherwise it's an error object.
//
-func Timeout(connectTimeoutSec, readWriteTimeout int64) ClientOption {
- return func(client *Client) {
- client.Config.HTTPTimeout.ConnectTimeout =
- time.Second * time.Duration(connectTimeoutSec)
- client.Config.HTTPTimeout.ReadWriteTimeout =
- time.Second * time.Duration(readWriteTimeout)
- client.Config.HTTPTimeout.HeaderTimeout =
- time.Second * time.Duration(readWriteTimeout)
- client.Config.HTTPTimeout.IdleConnTimeout =
- time.Second * time.Duration(readWriteTimeout)
- client.Config.HTTPTimeout.LongTimeout =
- time.Second * time.Duration(readWriteTimeout*10)
+func (client Client) PutBucketRTC(bucketName string, rtc PutBucketRTC, options ...Option) error {
+ bs, err := xml.Marshal(rtc)
+ if err != nil {
+ return err
}
+ err = client.PutBucketRTCXml(bucketName, string(bs), options...)
+ return err
}
-// SecurityToken sets the temporary user's SecurityToken.
-//
-// token STS token
+// PutBucketRTCXml put bucket rtc configuration
+// bucketName the bucket name.
+// xmlBody the rtc configuration in xml format.
+// error it's nil if no error, otherwise it's an error object.
//
-func SecurityToken(token string) ClientOption {
- return func(client *Client) {
- client.Config.SecurityToken = strings.TrimSpace(token)
+func (client Client) PutBucketRTCXml(bucketName string, xmlBody string, options ...Option) error {
+ buffer := new(bytes.Buffer)
+ buffer.Write([]byte(xmlBody))
+
+ contentType := http.DetectContentType(buffer.Bytes())
+ headers := map[string]string{}
+ headers[HTTPHeaderContentType] = contentType
+
+ params := map[string]interface{}{}
+ params["rtc"] = nil
+ resp, err := client.do("PUT", bucketName, params, headers, buffer, options...)
+ if err != nil {
+ return err
}
+ defer resp.Body.Close()
+ return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
}
-// EnableMD5 enables MD5 validation.
-//
-// isEnableMD5 true: enable MD5 validation; false: disable MD5 validation.
+// GetBucketReplication get bucket replication configuration
+// bucketName the bucket name.
+// string the replication configuration.
+// error it's nil if no error, otherwise it's an error object.
//
-func EnableMD5(isEnableMD5 bool) ClientOption {
- return func(client *Client) {
- client.Config.IsEnableMD5 = isEnableMD5
+func (client Client) GetBucketReplication(bucketName string, options ...Option) (string, error) {
+ params := map[string]interface{}{}
+ params["replication"] = nil
+
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
+ if err != nil {
+ return "", err
}
-}
+ defer resp.Body.Close()
-// MD5ThresholdCalcInMemory sets the memory usage threshold for computing the MD5, default is 16MB.
-//
-// threshold the memory threshold in bytes. When the uploaded content is more than 16MB, the temp file is used for computing the MD5.
-//
-func MD5ThresholdCalcInMemory(threshold int64) ClientOption {
- return func(client *Client) {
- client.Config.MD5Threshold = threshold
+ data, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return "", err
}
+ return string(data), err
}
-// EnableCRC enables the CRC checksum. Default is true.
-//
-// isEnableCRC true: enable CRC checksum; false: disable the CRC checksum.
+// DeleteBucketReplication delete bucket replication configuration
+// bucketName the bucket name.
+// ruleId the ID of the replication configuration.
+// error it's nil if no error, otherwise it's an error object.
//
-func EnableCRC(isEnableCRC bool) ClientOption {
- return func(client *Client) {
- client.Config.IsEnableCRC = isEnableCRC
+func (client Client) DeleteBucketReplication(bucketName string, ruleId string, options ...Option) error {
+ replicationxml := ReplicationXML{}
+ replicationxml.ID = ruleId
+
+ bs, err := xml.Marshal(replicationxml)
+ if err != nil {
+ return err
}
-}
-// UserAgent specifies UserAgent. The default is aliyun-sdk-go/1.2.0 (windows/-/amd64;go1.5.2).
-//
-// userAgent the user agent string.
-//
-func UserAgent(userAgent string) ClientOption {
- return func(client *Client) {
- client.Config.UserAgent = userAgent
- client.Config.UserSetUa = true
+ buffer := new(bytes.Buffer)
+ buffer.Write(bs)
+
+ contentType := http.DetectContentType(buffer.Bytes())
+ headers := map[string]string{}
+ headers[HTTPHeaderContentType] = contentType
+
+ params := map[string]interface{}{}
+ params["replication"] = nil
+ params["comp"] = "delete"
+ resp, err := client.do("POST", bucketName, params, headers, buffer, options...)
+ if err != nil {
+ return err
}
+ defer resp.Body.Close()
+ return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
}
-// Proxy sets the proxy (optional). The default is not using proxy.
-//
-// proxyHost the proxy host in the format "host:port". For example, proxy.com:80 .
+// GetBucketReplicationLocation get the locations of the target bucket that can be copied to
+// bucketName the bucket name.
+// string the locations of the target bucket that can be copied to.
+// error it's nil if no error, otherwise it's an error object.
//
-func Proxy(proxyHost string) ClientOption {
- return func(client *Client) {
- client.Config.IsUseProxy = true
- client.Config.ProxyHost = proxyHost
- client.Conn.url.Init(client.Config.Endpoint, client.Config.IsCname, client.Config.IsUseProxy)
+func (client Client) GetBucketReplicationLocation(bucketName string, options ...Option) (string, error) {
+ params := map[string]interface{}{}
+ params["replicationLocation"] = nil
+
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
+ if err != nil {
+ return "", err
}
-}
+ defer resp.Body.Close()
-// AuthProxy sets the proxy information with user name and password.
-//
-// proxyHost the proxy host in the format "host:port". For example, proxy.com:80 .
-// proxyUser the proxy user name.
-// proxyPassword the proxy password.
-//
-func AuthProxy(proxyHost, proxyUser, proxyPassword string) ClientOption {
- return func(client *Client) {
- client.Config.IsUseProxy = true
- client.Config.ProxyHost = proxyHost
- client.Config.IsAuthProxy = true
- client.Config.ProxyUser = proxyUser
- client.Config.ProxyPassword = proxyPassword
- client.Conn.url.Init(client.Config.Endpoint, client.Config.IsCname, client.Config.IsUseProxy)
+ data, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return "", err
}
+ return string(data), err
}
+// GetBucketReplicationProgress get the replication progress of bucket
+// bucketName the bucket name.
+// ruleId the ID of the replication configuration.
+// string the replication progress of bucket.
+// error it's nil if no error, otherwise it's an error object.
//
-// HTTPClient sets the http.Client in use to the one passed in
-//
-func HTTPClient(HTTPClient *http.Client) ClientOption {
- return func(client *Client) {
- client.HTTPClient = HTTPClient
+func (client Client) GetBucketReplicationProgress(bucketName string, ruleId string, options ...Option) (string, error) {
+ params := map[string]interface{}{}
+ params["replicationProgress"] = nil
+ if ruleId != "" {
+ params["rule-id"] = ruleId
}
-}
+
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
+ if err != nil {
+ return "", err
+ }
+ defer resp.Body.Close()
+
+ data, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return "", err
+ }
+ return string(data), err
+}
+
+// GetBucketAccessMonitor get bucket's access monitor config
+// bucketName the bucket name.
+// GetBucketAccessMonitorResult the access monitor configuration result of bucket.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) GetBucketAccessMonitor(bucketName string, options ...Option) (GetBucketAccessMonitorResult, error) {
+ var out GetBucketAccessMonitorResult
+ body, err := client.GetBucketAccessMonitorXml(bucketName, options...)
+ if err != nil {
+ return out, err
+ }
+ err = xmlUnmarshal(strings.NewReader(body), &out)
+ return out, err
+}
+
+// GetBucketAccessMonitorXml get bucket's access monitor config
+// bucketName the bucket name.
+// string the access monitor configuration result of bucket xml foramt.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) GetBucketAccessMonitorXml(bucketName string, options ...Option) (string, error) {
+ params := map[string]interface{}{}
+ params["accessmonitor"] = nil
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
+ if err != nil {
+ return "", err
+ }
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ out := string(body)
+ return out, err
+}
+
+// PutBucketAccessMonitor get bucket's access monitor config
+// bucketName the bucket name.
+// accessMonitor the access monitor configuration of bucket.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) PutBucketAccessMonitor(bucketName string, accessMonitor PutBucketAccessMonitor, options ...Option) error {
+ bs, err := xml.Marshal(accessMonitor)
+ if err != nil {
+ return err
+ }
+ err = client.PutBucketAccessMonitorXml(bucketName, string(bs), options...)
+ return err
+}
+
+// PutBucketAccessMonitorXml get bucket's access monitor config
+// bucketName the bucket name.
+// xmlData the access monitor configuration in xml foramt
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) PutBucketAccessMonitorXml(bucketName string, xmlData string, options ...Option) error {
+ buffer := new(bytes.Buffer)
+ buffer.Write([]byte(xmlData))
+ contentType := http.DetectContentType(buffer.Bytes())
+ headers := map[string]string{}
+ headers[HTTPHeaderContentType] = contentType
+ params := map[string]interface{}{}
+ params["accessmonitor"] = nil
+ resp, err := client.do("PUT", bucketName, params, nil, buffer, options...)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
+}
+
+// ListBucketCname list bucket's binding cname
+// bucketName the bucket name.
+// string the xml configuration of bucket.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) ListBucketCname(bucketName string, options ...Option) (ListBucketCnameResult, error) {
+ var out ListBucketCnameResult
+ body, err := client.GetBucketCname(bucketName, options...)
+ if err != nil {
+ return out, err
+ }
+ err = xmlUnmarshal(strings.NewReader(body), &out)
+ return out, err
+}
+
+// GetBucketCname get bucket's binding cname
+// bucketName the bucket name.
+// string the xml configuration of bucket.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) GetBucketCname(bucketName string, options ...Option) (string, error) {
+ params := map[string]interface{}{}
+ params["cname"] = nil
+
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
+ if err != nil {
+ return "", err
+ }
+ defer resp.Body.Close()
+
+ data, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return "", err
+ }
+ return string(data), err
+}
+
+// CreateBucketCnameToken create a token for the cname.
+// bucketName the bucket name.
+// cname a custom domain name.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) CreateBucketCnameToken(bucketName string, cname string, options ...Option) (CreateBucketCnameTokenResult, error) {
+ var out CreateBucketCnameTokenResult
+ params := map[string]interface{}{}
+ params["cname"] = nil
+ params["comp"] = "token"
+
+ rxml := CnameConfigurationXML{}
+ rxml.Domain = cname
+
+ bs, err := xml.Marshal(rxml)
+ if err != nil {
+ return out, err
+ }
+ buffer := new(bytes.Buffer)
+ buffer.Write(bs)
+
+ contentType := http.DetectContentType(buffer.Bytes())
+ headers := map[string]string{}
+ headers[HTTPHeaderContentType] = contentType
+
+ resp, err := client.do("POST", bucketName, params, headers, buffer, options...)
+ if err != nil {
+ return out, err
+ }
+ defer resp.Body.Close()
+
+ err = xmlUnmarshal(resp.Body, &out)
+ return out, err
+}
+
+// GetBucketCnameToken get a token for the cname
+// bucketName the bucket name.
+// cname a custom domain name.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) GetBucketCnameToken(bucketName string, cname string, options ...Option) (GetBucketCnameTokenResult, error) {
+ var out GetBucketCnameTokenResult
+ params := map[string]interface{}{}
+ params["cname"] = cname
+ params["comp"] = "token"
+
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
+ if err != nil {
+ return out, err
+ }
+ defer resp.Body.Close()
+
+ err = xmlUnmarshal(resp.Body, &out)
+ return out, err
+}
+
+// PutBucketCnameXml map a custom domain name to a bucket
+// bucketName the bucket name.
+// xmlBody the cname configuration in xml foramt
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) PutBucketCnameXml(bucketName string, xmlBody string, options ...Option) error {
+ params := map[string]interface{}{}
+ params["cname"] = nil
+ params["comp"] = "add"
+
+ buffer := new(bytes.Buffer)
+ buffer.Write([]byte(xmlBody))
+ contentType := http.DetectContentType(buffer.Bytes())
+ headers := map[string]string{}
+ headers[HTTPHeaderContentType] = contentType
+
+ resp, err := client.do("POST", bucketName, params, headers, buffer, options...)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
+}
+
+// PutBucketCname map a custom domain name to a bucket
+// bucketName the bucket name.
+// cname a custom domain name.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) PutBucketCname(bucketName string, cname string, options ...Option) error {
+ rxml := CnameConfigurationXML{}
+ rxml.Domain = cname
+ bs, err := xml.Marshal(rxml)
+ if err != nil {
+ return err
+ }
+ return client.PutBucketCnameXml(bucketName, string(bs), options...)
+}
+
+// PutBucketCnameWithCertificate map a custom domain name to a bucket
+// bucketName the bucket name.
+// PutBucketCname the bucket cname config in struct format.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) PutBucketCnameWithCertificate(bucketName string, putBucketCname PutBucketCname, options ...Option) error {
+ bs, err := xml.Marshal(putBucketCname)
+ if err != nil {
+ return err
+ }
+ return client.PutBucketCnameXml(bucketName, string(bs), options...)
+}
+
+// DeleteBucketCname remove the mapping of the custom domain name from a bucket.
+// bucketName the bucket name.
+// cname a custom domain name.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) DeleteBucketCname(bucketName string, cname string, options ...Option) error {
+ params := map[string]interface{}{}
+ params["cname"] = nil
+ params["comp"] = "delete"
+
+ rxml := CnameConfigurationXML{}
+ rxml.Domain = cname
+
+ bs, err := xml.Marshal(rxml)
+ if err != nil {
+ return err
+ }
+ buffer := new(bytes.Buffer)
+ buffer.Write(bs)
+
+ contentType := http.DetectContentType(buffer.Bytes())
+ headers := map[string]string{}
+ headers[HTTPHeaderContentType] = contentType
+
+ resp, err := client.do("POST", bucketName, params, headers, buffer, options...)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
+}
+
+// PutBucketResourceGroup set bucket's resource group
+// bucketName the bucket name.
+// resourceGroup the resource group configuration of bucket.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) PutBucketResourceGroup(bucketName string, resourceGroup PutBucketResourceGroup, options ...Option) error {
+ bs, err := xml.Marshal(resourceGroup)
+ if err != nil {
+ return err
+ }
+ err = client.PutBucketResourceGroupXml(bucketName, string(bs), options...)
+ return err
+}
+
+// PutBucketResourceGroupXml set bucket's resource group
+// bucketName the bucket name.
+// xmlData the resource group in xml format
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) PutBucketResourceGroupXml(bucketName string, xmlData string, options ...Option) error {
+ buffer := new(bytes.Buffer)
+ buffer.Write([]byte(xmlData))
+ contentType := http.DetectContentType(buffer.Bytes())
+ headers := map[string]string{}
+ headers[HTTPHeaderContentType] = contentType
+ params := map[string]interface{}{}
+ params["resourceGroup"] = nil
+ resp, err := client.do("PUT", bucketName, params, nil, buffer, options...)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
+}
+
+// GetBucketResourceGroup get bucket's resource group
+// bucketName the bucket name.
+// GetBucketResourceGroupResult the resource group configuration result of bucket.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) GetBucketResourceGroup(bucketName string, options ...Option) (GetBucketResourceGroupResult, error) {
+ var out GetBucketResourceGroupResult
+ body, err := client.GetBucketResourceGroupXml(bucketName, options...)
+ if err != nil {
+ return out, err
+ }
+ err = xmlUnmarshal(strings.NewReader(body), &out)
+ return out, err
+}
+
+// GetBucketResourceGroupXml get bucket's resource group
+// bucketName the bucket name.
+// string the resource group result of bucket xml format.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) GetBucketResourceGroupXml(bucketName string, options ...Option) (string, error) {
+ params := map[string]interface{}{}
+ params["resourceGroup"] = nil
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
+ if err != nil {
+ return "", err
+ }
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ out := string(body)
+ return out, err
+}
+
+// PutBucketStyle set bucket's style
+// bucketName the bucket name.
+// styleContent the style content.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) PutBucketStyle(bucketName, styleName string, styleContent string, options ...Option) error {
+ bs := fmt.Sprintf("", styleContent)
+ err := client.PutBucketStyleXml(bucketName, styleName, bs, options...)
+ return err
+}
+
+// PutBucketStyleXml set bucket's style
+// bucketName the bucket name.
+// styleName the style name.
+// xmlData the style in xml format
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) PutBucketStyleXml(bucketName, styleName, xmlData string, options ...Option) error {
+ buffer := new(bytes.Buffer)
+ buffer.Write([]byte(xmlData))
+ contentType := http.DetectContentType(buffer.Bytes())
+ headers := map[string]string{}
+ headers[HTTPHeaderContentType] = contentType
+ params := map[string]interface{}{}
+ params["style"] = nil
+ params["styleName"] = styleName
+ resp, err := client.do("PUT", bucketName, params, nil, buffer, options...)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
+}
+
+// GetBucketStyle get bucket's style
+// bucketName the bucket name.
+// styleName the bucket style name.
+// GetBucketStyleResult the style result of bucket.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) GetBucketStyle(bucketName, styleName string, options ...Option) (GetBucketStyleResult, error) {
+ var out GetBucketStyleResult
+ body, err := client.GetBucketStyleXml(bucketName, styleName, options...)
+ if err != nil {
+ return out, err
+ }
+ err = xmlUnmarshal(strings.NewReader(body), &out)
+ return out, err
+}
+
+// GetBucketStyleXml get bucket's style
+// bucketName the bucket name.
+// styleName the bucket style name.
+// string the style result of bucket in xml format.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) GetBucketStyleXml(bucketName, styleName string, options ...Option) (string, error) {
+ params := map[string]interface{}{}
+ params["style"] = nil
+ params["styleName"] = styleName
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
+ if err != nil {
+ return "", err
+ }
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ out := string(body)
+ return out, err
+}
+
+// ListBucketStyle get bucket's styles
+// bucketName the bucket name.
+// GetBucketListStyleResult the list style result of bucket.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) ListBucketStyle(bucketName string, options ...Option) (GetBucketListStyleResult, error) {
+ var out GetBucketListStyleResult
+ body, err := client.ListBucketStyleXml(bucketName, options...)
+ if err != nil {
+ return out, err
+ }
+ err = xmlUnmarshal(strings.NewReader(body), &out)
+ return out, err
+}
+
+// ListBucketStyleXml get bucket's list style
+// bucketName the bucket name.
+// string the style result of bucket in xml format.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) ListBucketStyleXml(bucketName string, options ...Option) (string, error) {
+ params := map[string]interface{}{}
+ params["style"] = nil
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
+ if err != nil {
+ return "", err
+ }
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ out := string(body)
+ return out, err
+}
+
+// DeleteBucketStyle delete bucket's style
+// bucketName the bucket name.
+// styleName the bucket style name.
+// string the style result of bucket in xml format.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) DeleteBucketStyle(bucketName, styleName string, options ...Option) error {
+ params := map[string]interface{}{}
+ params["style"] = bucketName
+ params["styleName"] = styleName
+ resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ return CheckRespCode(resp.StatusCode, []int{http.StatusNoContent})
+}
+
+// PutBucketResponseHeader set bucket response header
+// bucketName the bucket name.
+// xmlData the resource group in xml format
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) PutBucketResponseHeader(bucketName string, responseHeader PutBucketResponseHeader, options ...Option) error {
+ bs, err := xml.Marshal(responseHeader)
+ if err != nil {
+ return err
+ }
+ err = client.PutBucketResponseHeaderXml(bucketName, string(bs), options...)
+ return err
+}
+
+// PutBucketResponseHeaderXml set bucket response header
+// bucketName the bucket name.
+// xmlData the bucket response header in xml format
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) PutBucketResponseHeaderXml(bucketName, xmlData string, options ...Option) error {
+ buffer := new(bytes.Buffer)
+ buffer.Write([]byte(xmlData))
+ contentType := http.DetectContentType(buffer.Bytes())
+ headers := map[string]string{}
+ headers[HTTPHeaderContentType] = contentType
+ params := map[string]interface{}{}
+ params["responseHeader"] = nil
+ resp, err := client.do("PUT", bucketName, params, nil, buffer, options...)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
+}
+
+// GetBucketResponseHeader get bucket's response header.
+// bucketName the bucket name.
+// GetBucketResponseHeaderResult the response header result of bucket.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) GetBucketResponseHeader(bucketName string, options ...Option) (GetBucketResponseHeaderResult, error) {
+ var out GetBucketResponseHeaderResult
+ body, err := client.GetBucketResponseHeaderXml(bucketName, options...)
+ if err != nil {
+ return out, err
+ }
+ err = xmlUnmarshal(strings.NewReader(body), &out)
+ return out, err
+}
+
+// GetBucketResponseHeaderXml get bucket's resource group
+// bucketName the bucket name.
+// string the response header result of bucket xml format.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) GetBucketResponseHeaderXml(bucketName string, options ...Option) (string, error) {
+ params := map[string]interface{}{}
+ params["responseHeader"] = nil
+ resp, err := client.do("GET", bucketName, params, nil, nil, options...)
+ if err != nil {
+ return "", err
+ }
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ out := string(body)
+ return out, err
+}
+
+// DeleteBucketResponseHeader delete response header from a bucket.
+// bucketName the bucket name.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) DeleteBucketResponseHeader(bucketName string, options ...Option) error {
+ params := map[string]interface{}{}
+ params["responseHeader"] = nil
+ resp, err := client.do("DELETE", bucketName, params, nil, nil, options...)
+
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ return CheckRespCode(resp.StatusCode, []int{http.StatusNoContent})
+}
+
+// DescribeRegions get describe regions
+// GetDescribeRegionsResult the result of bucket in xml format.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) DescribeRegions(options ...Option) (DescribeRegionsResult, error) {
+ var out DescribeRegionsResult
+ body, err := client.DescribeRegionsXml(options...)
+ if err != nil {
+ return out, err
+ }
+ err = xmlUnmarshal(strings.NewReader(body), &out)
+ return out, err
+}
+
+// DescribeRegionsXml get describe regions
+// string the style result of bucket in xml format.
+// error it's nil if no error, otherwise it's an error object.
+func (client Client) DescribeRegionsXml(options ...Option) (string, error) {
+ params, err := GetRawParams(options)
+ if err != nil {
+ return "", err
+ }
+ if params["regions"] == nil {
+ params["regions"] = nil
+ }
+ resp, err := client.do("GET", "", params, nil, nil, options...)
+ if err != nil {
+ return "", err
+ }
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ out := string(body)
+ return out, err
+}
+
+// LimitUploadSpeed set upload bandwidth limit speed,default is 0,unlimited
+// upSpeed KB/s, 0 is unlimited,default is 0
+// error it's nil if success, otherwise failure
+func (client Client) LimitUploadSpeed(upSpeed int) error {
+ if client.Config == nil {
+ return fmt.Errorf("client config is nil")
+ }
+ return client.Config.LimitUploadSpeed(upSpeed)
+}
+
+// LimitDownloadSpeed set download bandwidth limit speed,default is 0,unlimited
+// downSpeed KB/s, 0 is unlimited,default is 0
+// error it's nil if success, otherwise failure
+func (client Client) LimitDownloadSpeed(downSpeed int) error {
+ if client.Config == nil {
+ return fmt.Errorf("client config is nil")
+ }
+ return client.Config.LimitDownloadSpeed(downSpeed)
+}
+
+// UseCname sets the flag of using CName. By default it's false.
+//
+// isUseCname true: the endpoint has the CName, false: the endpoint does not have cname. Default is false.
+//
+func UseCname(isUseCname bool) ClientOption {
+ return func(client *Client) {
+ client.Config.IsCname = isUseCname
+ }
+}
+
+// ForcePathStyle sets the flag of using Path Style. By default it's false.
+//
+// isPathStyle true: the endpoint has the Path Style, false: the endpoint does not have Path Style. Default is false.
+//
+func ForcePathStyle(isPathStyle bool) ClientOption {
+ return func(client *Client) {
+ client.Config.IsPathStyle = isPathStyle
+ }
+}
+
+// Timeout sets the HTTP timeout in seconds.
+//
+// connectTimeoutSec HTTP timeout in seconds. Default is 10 seconds. 0 means infinite (not recommended)
+// readWriteTimeout HTTP read or write's timeout in seconds. Default is 20 seconds. 0 means infinite.
+//
+func Timeout(connectTimeoutSec, readWriteTimeout int64) ClientOption {
+ return func(client *Client) {
+ client.Config.HTTPTimeout.ConnectTimeout =
+ time.Second * time.Duration(connectTimeoutSec)
+ client.Config.HTTPTimeout.ReadWriteTimeout =
+ time.Second * time.Duration(readWriteTimeout)
+ client.Config.HTTPTimeout.HeaderTimeout =
+ time.Second * time.Duration(readWriteTimeout)
+ client.Config.HTTPTimeout.IdleConnTimeout =
+ time.Second * time.Duration(readWriteTimeout)
+ client.Config.HTTPTimeout.LongTimeout =
+ time.Second * time.Duration(readWriteTimeout*10)
+ }
+}
+
+// MaxConns sets the HTTP max connections for a client.
+//
+// maxIdleConns controls the maximum number of idle (keep-alive) connections across all hosts. Default is 100.
+// maxIdleConnsPerHost controls the maximum idle (keep-alive) connections to keep per-host. Default is 100.
+// maxConnsPerHost limits the total number of connections per host. Default is no limit.
+//
+func MaxConns(maxIdleConns, maxIdleConnsPerHost, maxConnsPerHost int) ClientOption {
+ return func(client *Client) {
+ client.Config.HTTPMaxConns.MaxIdleConns = maxIdleConns
+ client.Config.HTTPMaxConns.MaxIdleConnsPerHost = maxIdleConnsPerHost
+ client.Config.HTTPMaxConns.MaxConnsPerHost = maxConnsPerHost
+ }
+}
+
+// SecurityToken sets the temporary user's SecurityToken.
+//
+// token STS token
+//
+func SecurityToken(token string) ClientOption {
+ return func(client *Client) {
+ client.Config.SecurityToken = strings.TrimSpace(token)
+ }
+}
+
+// EnableMD5 enables MD5 validation.
+//
+// isEnableMD5 true: enable MD5 validation; false: disable MD5 validation.
+//
+func EnableMD5(isEnableMD5 bool) ClientOption {
+ return func(client *Client) {
+ client.Config.IsEnableMD5 = isEnableMD5
+ }
+}
+
+// MD5ThresholdCalcInMemory sets the memory usage threshold for computing the MD5, default is 16MB.
+//
+// threshold the memory threshold in bytes. When the uploaded content is more than 16MB, the temp file is used for computing the MD5.
+//
+func MD5ThresholdCalcInMemory(threshold int64) ClientOption {
+ return func(client *Client) {
+ client.Config.MD5Threshold = threshold
+ }
+}
+
+// EnableCRC enables the CRC checksum. Default is true.
+//
+// isEnableCRC true: enable CRC checksum; false: disable the CRC checksum.
+//
+func EnableCRC(isEnableCRC bool) ClientOption {
+ return func(client *Client) {
+ client.Config.IsEnableCRC = isEnableCRC
+ }
+}
+
+// UserAgent specifies UserAgent. The default is aliyun-sdk-go/1.2.0 (windows/-/amd64;go1.5.2).
+//
+// userAgent the user agent string.
+//
+func UserAgent(userAgent string) ClientOption {
+ return func(client *Client) {
+ client.Config.UserAgent = userAgent
+ client.Config.UserSetUa = true
+ }
+}
+
+// Proxy sets the proxy (optional). The default is not using proxy.
+//
+// proxyHost the proxy host in the format "host:port". For example, proxy.com:80 .
+//
+func Proxy(proxyHost string) ClientOption {
+ return func(client *Client) {
+ client.Config.IsUseProxy = true
+ client.Config.ProxyHost = proxyHost
+ }
+}
+
+// AuthProxy sets the proxy information with user name and password.
+//
+// proxyHost the proxy host in the format "host:port". For example, proxy.com:80 .
+// proxyUser the proxy user name.
+// proxyPassword the proxy password.
+//
+func AuthProxy(proxyHost, proxyUser, proxyPassword string) ClientOption {
+ return func(client *Client) {
+ client.Config.IsUseProxy = true
+ client.Config.ProxyHost = proxyHost
+ client.Config.IsAuthProxy = true
+ client.Config.ProxyUser = proxyUser
+ client.Config.ProxyPassword = proxyPassword
+ }
+}
+
+//
+// HTTPClient sets the http.Client in use to the one passed in
+//
+func HTTPClient(HTTPClient *http.Client) ClientOption {
+ return func(client *Client) {
+ client.HTTPClient = HTTPClient
+ }
+}
//
// SetLogLevel sets the oss sdk log level
@@ -1736,14 +2845,14 @@ func SetLogger(Logger *log.Logger) ClientOption {
}
}
-// SetCredentialsProvider sets funciton for get the user's ak
+// SetCredentialsProvider sets function for get the user's ak
func SetCredentialsProvider(provider CredentialsProvider) ClientOption {
return func(client *Client) {
client.Config.CredentialsProvider = provider
}
}
-// SetLocalAddr sets funciton for local addr
+// SetLocalAddr sets function for local addr
func SetLocalAddr(localAddr net.Addr) ClientOption {
return func(client *Client) {
client.Config.LocalAddr = localAddr
@@ -1764,13 +2873,48 @@ func AdditionalHeaders(headers []string) ClientOption {
}
}
-// only effective from go1.7 onward,RedirectEnabled set http redirect enabled or not
+// RedirectEnabled only effective from go1.7 onward,RedirectEnabled set http redirect enabled or not
func RedirectEnabled(enabled bool) ClientOption {
return func(client *Client) {
client.Config.RedirectEnabled = enabled
}
}
+// InsecureSkipVerify skip verifying tls certificate file
+func InsecureSkipVerify(enabled bool) ClientOption {
+ return func(client *Client) {
+ client.Config.InsecureSkipVerify = enabled
+ }
+}
+
+// Region set region
+func Region(region string) ClientOption {
+ return func(client *Client) {
+ client.Config.Region = region
+ }
+}
+
+// CloudBoxId set cloudBox id
+func CloudBoxId(cloudBoxId string) ClientOption {
+ return func(client *Client) {
+ client.Config.CloudBoxId = cloudBoxId
+ }
+}
+
+// Product set product type
+func Product(product string) ClientOption {
+ return func(client *Client) {
+ client.Config.Product = product
+ }
+}
+
+// VerifyObjectStrict sets the flag of verifying object name strictly.
+func VerifyObjectStrict(enable bool) ClientOption {
+ return func(client *Client) {
+ client.Config.VerifyObjectStrict = enable
+ }
+}
+
// Private
func (client Client) do(method, bucketName string, params map[string]interface{},
headers map[string]string, data io.Reader, options ...Option) (*Response, error) {
@@ -1803,7 +2947,9 @@ func (client Client) do(method, bucketName string, params map[string]interface{}
respHeader, _ := FindOption(options, responseHeader, nil)
if respHeader != nil {
pRespHeader := respHeader.(*http.Header)
- *pRespHeader = resp.Headers
+ if resp != nil {
+ *pRespHeader = resp.Headers
+ }
}
return resp, err
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/conf.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/conf.go
index 55e5e370a..305fbcf12 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/conf.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/conf.go
@@ -34,20 +34,26 @@ type HTTPTimeout struct {
type HTTPMaxConns struct {
MaxIdleConns int
MaxIdleConnsPerHost int
+ MaxConnsPerHost int
}
-// CredentialInf is interface for get AccessKeyID,AccessKeySecret,SecurityToken
+// Credentials is interface for get AccessKeyID,AccessKeySecret,SecurityToken
type Credentials interface {
GetAccessKeyID() string
GetAccessKeySecret() string
GetSecurityToken() string
}
-// CredentialInfBuild is interface for get CredentialInf
+// CredentialsProvider is interface for get Credential Info
type CredentialsProvider interface {
GetCredentials() Credentials
}
+type CredentialsProviderE interface {
+ CredentialsProvider
+ GetCredentialsE() (Credentials, error)
+}
+
type defaultCredentials struct {
config *Config
}
@@ -72,6 +78,68 @@ func (defBuild *defaultCredentialsProvider) GetCredentials() Credentials {
return &defaultCredentials{config: defBuild.config}
}
+type envCredentials struct {
+ AccessKeyId string
+ AccessKeySecret string
+ SecurityToken string
+}
+
+type EnvironmentVariableCredentialsProvider struct {
+ cred Credentials
+}
+
+func (credentials *envCredentials) GetAccessKeyID() string {
+ return credentials.AccessKeyId
+}
+
+func (credentials *envCredentials) GetAccessKeySecret() string {
+ return credentials.AccessKeySecret
+}
+
+func (credentials *envCredentials) GetSecurityToken() string {
+ return credentials.SecurityToken
+}
+
+func (defBuild *EnvironmentVariableCredentialsProvider) GetCredentials() Credentials {
+ var accessID, accessKey, token string
+ if defBuild.cred == nil {
+ accessID = os.Getenv("OSS_ACCESS_KEY_ID")
+ accessKey = os.Getenv("OSS_ACCESS_KEY_SECRET")
+ token = os.Getenv("OSS_SESSION_TOKEN")
+ } else {
+ accessID = defBuild.cred.GetAccessKeyID()
+ accessKey = defBuild.cred.GetAccessKeySecret()
+ token = defBuild.cred.GetSecurityToken()
+ }
+
+ return &envCredentials{
+ AccessKeyId: accessID,
+ AccessKeySecret: accessKey,
+ SecurityToken: token,
+ }
+}
+
+func NewEnvironmentVariableCredentialsProvider() (EnvironmentVariableCredentialsProvider, error) {
+ var provider EnvironmentVariableCredentialsProvider
+ accessID := os.Getenv("OSS_ACCESS_KEY_ID")
+ if accessID == "" {
+ return provider, fmt.Errorf("access key id is empty!")
+ }
+ accessKey := os.Getenv("OSS_ACCESS_KEY_SECRET")
+ if accessKey == "" {
+ return provider, fmt.Errorf("access key secret is empty!")
+ }
+ token := os.Getenv("OSS_SESSION_TOKEN")
+ envCredential := &envCredentials{
+ AccessKeyId: accessID,
+ AccessKeySecret: accessKey,
+ SecurityToken: token,
+ }
+ return EnvironmentVariableCredentialsProvider{
+ cred: envCredential,
+ }, nil
+}
+
// Config defines oss configuration
type Config struct {
Endpoint string // OSS endpoint
@@ -83,6 +151,7 @@ type Config struct {
Timeout uint // Timeout in seconds. By default it's 60.
SecurityToken string // STS Token
IsCname bool // If cname is in the endpoint.
+ IsPathStyle bool // If Path Style is in the endpoint.
HTTPTimeout HTTPTimeout // HTTP timeout
HTTPMaxConns HTTPMaxConns // Http max connections
IsUseProxy bool // Flag of using proxy.
@@ -97,12 +166,19 @@ type Config struct {
Logger *log.Logger // For write log
UploadLimitSpeed int // Upload limit speed:KB/s, 0 is unlimited
UploadLimiter *OssLimiter // Bandwidth limit reader for upload
+ DownloadLimitSpeed int // Download limit speed:KB/s, 0 is unlimited
+ DownloadLimiter *OssLimiter // Bandwidth limit reader for download
CredentialsProvider CredentialsProvider // User provides interface to get AccessKeyID, AccessKeySecret, SecurityToken
LocalAddr net.Addr // local client host info
UserSetUa bool // UserAgent is set by user or not
- AuthVersion AuthVersionType // v1 or v2 signature,default is v1
+ AuthVersion AuthVersionType // v1 or v2, v4 signature,default is v1
AdditionalHeaders []string // special http headers needed to be sign
RedirectEnabled bool // only effective from go1.7 onward, enable http redirect or not
+ InsecureSkipVerify bool // for https, Whether to skip verifying the server certificate file
+ Region string // such as cn-hangzhou
+ CloudBoxId string //
+ Product string // oss or oss-cloudbox, default is oss
+ VerifyObjectStrict bool // a flag of verifying object name strictly. Default is enable.
}
// LimitUploadSpeed uploadSpeed:KB/s, 0 is unlimited,default is 0
@@ -123,6 +199,24 @@ func (config *Config) LimitUploadSpeed(uploadSpeed int) error {
return err
}
+// LimitDownLoadSpeed downloadSpeed:KB/s, 0 is unlimited,default is 0
+func (config *Config) LimitDownloadSpeed(downloadSpeed int) error {
+ if downloadSpeed < 0 {
+ return fmt.Errorf("invalid argument, the value of downloadSpeed is less than 0")
+ } else if downloadSpeed == 0 {
+ config.DownloadLimitSpeed = 0
+ config.DownloadLimiter = nil
+ return nil
+ }
+
+ var err error
+ config.DownloadLimiter, err = GetOssLimiter(downloadSpeed)
+ if err == nil {
+ config.DownloadLimitSpeed = downloadSpeed
+ }
+ return err
+}
+
// WriteLog output log function
func (config *Config) WriteLog(LogLevel int, format string, a ...interface{}) {
if config.LogLevel < LogLevel || config.Logger == nil {
@@ -140,6 +234,22 @@ func (config *Config) GetCredentials() Credentials {
return config.CredentialsProvider.GetCredentials()
}
+// for get Sign Product
+func (config *Config) GetSignProduct() string {
+ if config.CloudBoxId != "" {
+ return "oss-cloudbox"
+ }
+ return "oss"
+}
+
+// for get Sign Region
+func (config *Config) GetSignRegion() string {
+ if config.CloudBoxId != "" {
+ return config.CloudBoxId
+ }
+ return config.Region
+}
+
// getDefaultOssConfig gets the default configuration.
func getDefaultOssConfig() *Config {
config := Config{}
@@ -153,6 +263,7 @@ func getDefaultOssConfig() *Config {
config.Timeout = 60 // Seconds
config.SecurityToken = ""
config.IsCname = false
+ config.IsPathStyle = false
config.HTTPTimeout.ConnectTimeout = time.Second * 30 // 30s
config.HTTPTimeout.ReadWriteTimeout = time.Second * 60 // 60s
@@ -180,6 +291,11 @@ func getDefaultOssConfig() *Config {
config.AuthVersion = AuthV1
config.RedirectEnabled = true
+ config.InsecureSkipVerify = false
+
+ config.Product = "oss"
+
+ config.VerifyObjectStrict = true
return &config
}
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/conn.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/conn.go
index fbbb1bb7e..86e2b6f2f 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/conn.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/conn.go
@@ -2,6 +2,7 @@ package oss
import (
"bytes"
+ "context"
"crypto/md5"
"encoding/base64"
"encoding/json"
@@ -48,8 +49,16 @@ var signKeyList = []string{"acl", "uploads", "location", "cors",
"worm", "wormId", "wormExtend", "withHashContext",
"x-oss-enable-md5", "x-oss-enable-sha1", "x-oss-enable-sha256",
"x-oss-hash-ctx", "x-oss-md5-ctx", "transferAcceleration",
+ "regionList", "cloudboxes", "x-oss-ac-source-ip", "x-oss-ac-subnet-mask", "x-oss-ac-vpc-id", "x-oss-ac-forward-allow",
+ "metaQuery", "resourceGroup", "rtc", "x-oss-async-process", "responseHeader",
}
+const (
+ timeFormatV4 = "20060102T150405Z"
+ shortTimeFormatV4 = "20060102"
+ signingAlgorithmV4 = "OSS4-HMAC-SHA256"
+)
+
// init initializes Conn
func (conn *Conn) init(config *Config, urlMaker *urlMaker, client *http.Client) error {
if client == nil {
@@ -86,16 +95,35 @@ func (conn *Conn) init(config *Config, urlMaker *urlMaker, client *http.Client)
// Do sends request and returns the response
func (conn Conn) Do(method, bucketName, objectName string, params map[string]interface{}, headers map[string]string,
+ data io.Reader, initCRC uint64, listener ProgressListener) (*Response, error) {
+ return conn.DoWithContext(nil, method, bucketName, objectName, params, headers, data, initCRC, listener)
+}
+
+// DoWithContext sends request and returns the response with context
+func (conn Conn) DoWithContext(ctx context.Context, method, bucketName, objectName string, params map[string]interface{}, headers map[string]string,
data io.Reader, initCRC uint64, listener ProgressListener) (*Response, error) {
urlParams := conn.getURLParams(params)
subResource := conn.getSubResource(params)
uri := conn.url.getURL(bucketName, objectName, urlParams)
- resource := conn.getResource(bucketName, objectName, subResource)
- return conn.doRequest(method, uri, resource, headers, data, initCRC, listener)
+
+ resource := ""
+ if conn.config.AuthVersion != AuthV4 {
+ resource = conn.getResource(bucketName, objectName, subResource)
+ } else {
+ resource = conn.getResourceV4(bucketName, objectName, subResource)
+ }
+
+ return conn.doRequest(ctx, method, uri, resource, headers, data, initCRC, listener)
}
// DoURL sends the request with signed URL and returns the response result.
func (conn Conn) DoURL(method HTTPMethod, signedURL string, headers map[string]string,
+ data io.Reader, initCRC uint64, listener ProgressListener) (*Response, error) {
+ return conn.DoURLWithContext(nil, method, signedURL, headers, data, initCRC, listener)
+}
+
+// DoURLWithContext sends the request with signed URL and context and returns the response result.
+func (conn Conn) DoURLWithContext(ctx context.Context, method HTTPMethod, signedURL string, headers map[string]string,
data io.Reader, initCRC uint64, listener ProgressListener) (*Response, error) {
// Get URI from signedURL
uri, err := url.ParseRequestURI(signedURL)
@@ -114,6 +142,9 @@ func (conn Conn) DoURL(method HTTPMethod, signedURL string, headers map[string]s
Host: uri.Host,
}
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
tracker := &readerTracker{completedBytes: 0}
fd, crc := conn.handleBody(req, data, initCRC, listener, tracker)
if fd != nil {
@@ -149,9 +180,10 @@ func (conn Conn) DoURL(method HTTPMethod, signedURL string, headers map[string]s
resp, err := conn.client.Do(req)
if err != nil {
// Transfer failed
+ conn.config.WriteLog(Debug, "[Resp:%p]http error:%s\n", req, err.Error())
event = newProgressEvent(TransferFailedEvent, tracker.completedBytes, req.ContentLength, 0)
publishProgress(listener, event)
- conn.config.WriteLog(Debug, "[Resp:%p]http error:%s\n", req, err.Error())
+
return nil, err
}
@@ -182,7 +214,7 @@ func (conn Conn) getURLParams(params map[string]interface{}) string {
buf.WriteByte('&')
}
buf.WriteString(url.QueryEscape(k))
- if params[k] != nil {
+ if params[k] != nil && params[k].(string) != "" {
buf.WriteString("=" + strings.Replace(url.QueryEscape(params[k].(string)), "+", "%20", -1))
}
}
@@ -195,7 +227,7 @@ func (conn Conn) getSubResource(params map[string]interface{}) string {
keys := make([]string, 0, len(params))
signParams := make(map[string]string)
for k := range params {
- if conn.config.AuthVersion == AuthV2 {
+ if conn.config.AuthVersion == AuthV2 || conn.config.AuthVersion == AuthV4 {
encodedKey := url.QueryEscape(k)
keys = append(keys, encodedKey)
if params[k] != nil && params[k] != "" {
@@ -218,7 +250,9 @@ func (conn Conn) getSubResource(params map[string]interface{}) string {
}
buf.WriteString(k)
if _, ok := signParams[k]; ok {
- buf.WriteString("=" + signParams[k])
+ if signParams[k] != "" {
+ buf.WriteString("=" + signParams[k])
+ }
}
}
return buf.String()
@@ -250,10 +284,31 @@ func (conn Conn) getResource(bucketName, objectName, subResource string) string
return fmt.Sprintf("/%s/%s%s", bucketName, objectName, subResource)
}
-func (conn Conn) doRequest(method string, uri *url.URL, canonicalizedResource string, headers map[string]string,
+// getResource gets canonicalized resource
+func (conn Conn) getResourceV4(bucketName, objectName, subResource string) string {
+ if subResource != "" {
+ subResource = "?" + subResource
+ }
+
+ if bucketName == "" {
+ return fmt.Sprintf("/%s", subResource)
+ }
+
+ if objectName != "" {
+ objectName = url.QueryEscape(objectName)
+ objectName = strings.Replace(objectName, "+", "%20", -1)
+ objectName = strings.Replace(objectName, "%2F", "/", -1)
+ return fmt.Sprintf("/%s/%s%s", bucketName, objectName, subResource)
+ }
+ return fmt.Sprintf("/%s/%s", bucketName, subResource)
+}
+
+func (conn Conn) doRequest(ctx context.Context, method string, uri *url.URL, canonicalizedResource string, headers map[string]string,
data io.Reader, initCRC uint64, listener ProgressListener) (*Response, error) {
method = strings.ToUpper(method)
- req := &http.Request{
+ var req *http.Request
+ var err error
+ req = &http.Request{
Method: method,
URL: uri,
Proto: "HTTP/1.1",
@@ -262,7 +317,9 @@ func (conn Conn) doRequest(method string, uri *url.URL, canonicalizedResource st
Header: make(http.Header),
Host: uri.Host,
}
-
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
tracker := &readerTracker{completedBytes: 0}
fd, crc := conn.handleBody(req, data, initCRC, listener, tracker)
if fd != nil {
@@ -278,12 +335,24 @@ func (conn Conn) doRequest(method string, uri *url.URL, canonicalizedResource st
req.Header.Set("Proxy-Authorization", basic)
}
- date := time.Now().UTC().Format(http.TimeFormat)
- req.Header.Set(HTTPHeaderDate, date)
+ stNow := time.Now().UTC()
+ req.Header.Set(HTTPHeaderDate, stNow.Format(http.TimeFormat))
req.Header.Set(HTTPHeaderHost, req.Host)
req.Header.Set(HTTPHeaderUserAgent, conn.config.UserAgent)
- akIf := conn.config.GetCredentials()
+ if conn.config.AuthVersion == AuthV4 {
+ req.Header.Set(HttpHeaderOssContentSha256, DefaultContentSha256)
+ }
+
+ var akIf Credentials
+ if providerE, ok := conn.config.CredentialsProvider.(CredentialsProviderE); ok {
+ if akIf, err = providerE.GetCredentialsE(); err != nil {
+ return nil, err
+ }
+ } else {
+ akIf = conn.config.GetCredentials()
+ }
+
if akIf.GetSecurityToken() != "" {
req.Header.Set(HTTPHeaderOssSecurityToken, akIf.GetSecurityToken())
}
@@ -294,7 +363,7 @@ func (conn Conn) doRequest(method string, uri *url.URL, canonicalizedResource st
}
}
- conn.signHeader(req, canonicalizedResource)
+ conn.signHeader(req, canonicalizedResource, akIf)
// Transfer started
event := newProgressEvent(TransferStartedEvent, 0, req.ContentLength, 0)
@@ -307,10 +376,10 @@ func (conn Conn) doRequest(method string, uri *url.URL, canonicalizedResource st
resp, err := conn.client.Do(req)
if err != nil {
+ conn.config.WriteLog(Debug, "[Resp:%p]http error:%s\n", req, err.Error())
// Transfer failed
event = newProgressEvent(TransferFailedEvent, tracker.completedBytes, req.ContentLength, 0)
publishProgress(listener, event)
- conn.config.WriteLog(Debug, "[Resp:%p]http error:%s\n", req, err.Error())
return nil, err
}
@@ -326,10 +395,15 @@ func (conn Conn) doRequest(method string, uri *url.URL, canonicalizedResource st
return conn.handleResponse(resp, crc)
}
-func (conn Conn) signURL(method HTTPMethod, bucketName, objectName string, expiration int64, params map[string]interface{}, headers map[string]string) string {
- akIf := conn.config.GetCredentials()
- if akIf.GetSecurityToken() != "" {
- params[HTTPParamSecurityToken] = akIf.GetSecurityToken()
+func (conn Conn) signURL(method HTTPMethod, bucketName, objectName string, expiration int64, params map[string]interface{}, headers map[string]string) (string, error) {
+ var akIf Credentials
+ var err error
+ if providerE, ok := conn.config.CredentialsProvider.(CredentialsProviderE); ok {
+ if akIf, err = providerE.GetCredentialsE(); err != nil {
+ return "", err
+ }
+ } else {
+ akIf = conn.config.GetCredentials()
}
m := strings.ToUpper(string(method))
@@ -344,38 +418,74 @@ func (conn Conn) signURL(method HTTPMethod, bucketName, objectName string, expir
req.Header.Set("Proxy-Authorization", basic)
}
- req.Header.Set(HTTPHeaderDate, strconv.FormatInt(expiration, 10))
- req.Header.Set(HTTPHeaderUserAgent, conn.config.UserAgent)
+ if conn.config.AuthVersion == AuthV4 {
+ if akIf.GetSecurityToken() != "" {
+ params[HTTPParamOssSecurityToken] = akIf.GetSecurityToken()
+ }
- if headers != nil {
- for k, v := range headers {
- req.Header.Set(k, v)
+ if headers != nil {
+ for k, v := range headers {
+ req.Header.Set(k, v)
+ }
}
- }
- if conn.config.AuthVersion == AuthV2 {
- params[HTTPParamSignatureVersion] = "OSS2"
- params[HTTPParamExpiresV2] = strconv.FormatInt(expiration, 10)
- params[HTTPParamAccessKeyIDV2] = conn.config.AccessKeyID
+ now := time.Now().UTC()
+ expires := expiration - now.Unix()
+ product := conn.config.GetSignProduct()
+ region := conn.config.GetSignRegion()
+ strDay := now.Format(shortTimeFormatV4)
additionalList, _ := conn.getAdditionalHeaderKeys(req)
+
+ params[HTTPParamSignatureVersion] = signingAlgorithmV4
+ params[HTTPParamCredential] = fmt.Sprintf("%s/%s/%s/%s/aliyun_v4_request", akIf.GetAccessKeyID(), strDay, region, product)
+ params[HTTPParamDate] = now.Format(timeFormatV4)
+ params[HTTPParamExpiresV2] = strconv.FormatInt(expires, 10)
if len(additionalList) > 0 {
params[HTTPParamAdditionalHeadersV2] = strings.Join(additionalList, ";")
}
- }
- subResource := conn.getSubResource(params)
- canonicalizedResource := conn.getResource(bucketName, objectName, subResource)
- signedStr := conn.getSignedStr(req, canonicalizedResource, akIf.GetAccessKeySecret())
+ subResource := conn.getSubResource(params)
+ canonicalizedResource := conn.getResourceV4(bucketName, objectName, subResource)
+ authorizationStr := conn.getSignedStrV4(req, canonicalizedResource, akIf.GetAccessKeySecret(), &now)
+ params[HTTPParamSignatureV2] = authorizationStr
+ } else {
+ if akIf.GetSecurityToken() != "" {
+ params[HTTPParamSecurityToken] = akIf.GetSecurityToken()
+ }
- if conn.config.AuthVersion == AuthV1 {
- params[HTTPParamExpires] = strconv.FormatInt(expiration, 10)
- params[HTTPParamAccessKeyID] = akIf.GetAccessKeyID()
- params[HTTPParamSignature] = signedStr
- } else if conn.config.AuthVersion == AuthV2 {
- params[HTTPParamSignatureV2] = signedStr
+ req.Header.Set(HTTPHeaderDate, strconv.FormatInt(expiration, 10))
+
+ if headers != nil {
+ for k, v := range headers {
+ req.Header.Set(k, v)
+ }
+ }
+
+ if conn.config.AuthVersion == AuthV2 {
+ params[HTTPParamSignatureVersion] = "OSS2"
+ params[HTTPParamExpiresV2] = strconv.FormatInt(expiration, 10)
+ params[HTTPParamAccessKeyIDV2] = conn.config.AccessKeyID
+ additionalList, _ := conn.getAdditionalHeaderKeys(req)
+ if len(additionalList) > 0 {
+ params[HTTPParamAdditionalHeadersV2] = strings.Join(additionalList, ";")
+ }
+ }
+
+ subResource := conn.getSubResource(params)
+ canonicalizedResource := conn.getResource(bucketName, objectName, subResource)
+ signedStr := conn.getSignedStr(req, canonicalizedResource, akIf.GetAccessKeySecret())
+
+ if conn.config.AuthVersion == AuthV1 {
+ params[HTTPParamExpires] = strconv.FormatInt(expiration, 10)
+ params[HTTPParamAccessKeyID] = akIf.GetAccessKeyID()
+ params[HTTPParamSignature] = signedStr
+ } else if conn.config.AuthVersion == AuthV2 {
+ params[HTTPParamSignatureV2] = signedStr
+ }
}
+
urlParams := conn.getURLParams(params)
- return conn.url.getSignURL(bucketName, objectName, urlParams)
+ return conn.url.getSignURL(bucketName, objectName, urlParams), nil
}
func (conn Conn) signRtmpURL(bucketName, channelName, playlistName string, expiration int64) string {
@@ -468,58 +578,131 @@ func (conn Conn) handleResponse(resp *http.Response, crc hash.Hash64) (*Response
var srvCRC uint64
statusCode := resp.StatusCode
- if statusCode >= 400 && statusCode <= 505 {
- // 4xx and 5xx indicate that the operation has error occurred
- var respBody []byte
- respBody, err := readResponseBody(resp)
- if err != nil {
- return nil, err
- }
-
- if len(respBody) == 0 {
- err = ServiceError{
- StatusCode: statusCode,
- RequestID: resp.Header.Get(HTTPHeaderOssRequestID),
+ if statusCode/100 != 2 {
+ if statusCode >= 400 && statusCode <= 505 {
+ // 4xx and 5xx indicate that the operation has error occurred
+ var respBody []byte
+ var errorXml []byte
+ respBody, err := readResponseBody(resp)
+ if err != nil {
+ return nil, err
+ }
+ errorXml = respBody
+ if len(respBody) == 0 && len(resp.Header.Get(HTTPHeaderOssErr)) > 0 {
+ errorXml, err = base64.StdEncoding.DecodeString(resp.Header.Get(HTTPHeaderOssErr))
+ if err != nil {
+ errorXml = respBody
+ }
}
+ if len(errorXml) == 0 {
+ err = ServiceError{
+ StatusCode: statusCode,
+ RequestID: resp.Header.Get(HTTPHeaderOssRequestID),
+ Ec: resp.Header.Get(HTTPHeaderOssEc),
+ }
+ } else {
+ srvErr, errIn := serviceErrFromXML(errorXml, resp.StatusCode,
+ resp.Header.Get(HTTPHeaderOssRequestID))
+ if errIn != nil { // error unmarshal the error response
+ if len(resp.Header.Get(HTTPHeaderOssEc)) > 0 {
+ err = fmt.Errorf("oss: service returned invalid response body, status = %s, RequestId = %s, ec = %s", resp.Status, resp.Header.Get(HTTPHeaderOssRequestID), resp.Header.Get(HTTPHeaderOssEc))
+ } else {
+ err = fmt.Errorf("oss: service returned invalid response body, status = %s, RequestId = %s", resp.Status, resp.Header.Get(HTTPHeaderOssRequestID))
+ }
+ } else {
+ err = srvErr
+ }
+ }
+ return &Response{
+ StatusCode: resp.StatusCode,
+ Headers: resp.Header,
+ Body: ioutil.NopCloser(bytes.NewReader(respBody)), // restore the body
+ }, err
+ } else if statusCode >= 300 && statusCode <= 307 {
+ // OSS use 3xx, but response has no body
+ err := fmt.Errorf("oss: service returned %d,%s", resp.StatusCode, resp.Status)
+ return &Response{
+ StatusCode: resp.StatusCode,
+ Headers: resp.Header,
+ Body: resp.Body,
+ }, err
} else {
- // Response contains storage service error object, unmarshal
- srvErr, errIn := serviceErrFromXML(respBody, resp.StatusCode,
- resp.Header.Get(HTTPHeaderOssRequestID))
- if errIn != nil { // error unmarshaling the error response
- err = fmt.Errorf("oss: service returned invalid response body, status = %s, RequestId = %s", resp.Status, resp.Header.Get(HTTPHeaderOssRequestID))
+ // (0,300) [308,400) [506,)
+ // Other extended http StatusCode
+ var respBody []byte
+ var errorXml []byte
+ respBody, err := readResponseBody(resp)
+ if err != nil {
+ return &Response{StatusCode: resp.StatusCode, Headers: resp.Header, Body: ioutil.NopCloser(bytes.NewReader(respBody))}, err
+ }
+ errorXml = respBody
+ if len(respBody) == 0 && len(resp.Header.Get(HTTPHeaderOssErr)) > 0 {
+ errorXml, err = base64.StdEncoding.DecodeString(resp.Header.Get(HTTPHeaderOssErr))
+ if err != nil {
+ errorXml = respBody
+ }
+ }
+ if len(errorXml) == 0 {
+ err = ServiceError{
+ StatusCode: statusCode,
+ RequestID: resp.Header.Get(HTTPHeaderOssRequestID),
+ Ec: resp.Header.Get(HTTPHeaderOssEc),
+ }
} else {
- err = srvErr
+ srvErr, errIn := serviceErrFromXML(errorXml, resp.StatusCode,
+ resp.Header.Get(HTTPHeaderOssRequestID))
+ if errIn != nil { // error unmarshal the error response
+ if len(resp.Header.Get(HTTPHeaderOssEc)) > 0 {
+ err = fmt.Errorf("unknown response body, status = %s, RequestId = %s, ec = %s", resp.Status, resp.Header.Get(HTTPHeaderOssRequestID), resp.Header.Get(HTTPHeaderOssEc))
+ } else {
+ err = fmt.Errorf("unknown response body, status = %s, RequestId = %s", resp.Status, resp.Header.Get(HTTPHeaderOssRequestID))
+ }
+ } else {
+ err = srvErr
+ }
}
+ return &Response{
+ StatusCode: resp.StatusCode,
+ Headers: resp.Header,
+ Body: ioutil.NopCloser(bytes.NewReader(respBody)), // restore the body
+ }, err
+ }
+ } else {
+ if conn.config.IsEnableCRC && crc != nil {
+ cliCRC = crc.Sum64()
}
+ srvCRC, _ = strconv.ParseUint(resp.Header.Get(HTTPHeaderOssCRC64), 10, 64)
+ realBody := resp.Body
+ if conn.isDownloadLimitResponse(resp) {
+ limitReader := &LimitSpeedReader{
+ reader: realBody,
+ ossLimiter: conn.config.DownloadLimiter,
+ }
+ realBody = limitReader
+ }
+
+ // 2xx, successful
return &Response{
StatusCode: resp.StatusCode,
Headers: resp.Header,
- Body: ioutil.NopCloser(bytes.NewReader(respBody)), // restore the body
- }, err
- } else if statusCode >= 300 && statusCode <= 307 {
- // OSS use 3xx, but response has no body
- err := fmt.Errorf("oss: service returned %d,%s", resp.StatusCode, resp.Status)
- return &Response{
- StatusCode: resp.StatusCode,
- Headers: resp.Header,
- Body: resp.Body,
- }, err
+ Body: realBody,
+ ClientCRC: cliCRC,
+ ServerCRC: srvCRC,
+ }, nil
}
+}
- if conn.config.IsEnableCRC && crc != nil {
- cliCRC = crc.Sum64()
+// isUploadLimitReq: judge limit upload speed or not
+func (conn Conn) isDownloadLimitResponse(resp *http.Response) bool {
+ if resp == nil || conn.config.DownloadLimitSpeed == 0 || conn.config.DownloadLimiter == nil {
+ return false
}
- srvCRC, _ = strconv.ParseUint(resp.Header.Get(HTTPHeaderOssCRC64), 10, 64)
- // 2xx, successful
- return &Response{
- StatusCode: resp.StatusCode,
- Headers: resp.Header,
- Body: resp.Body,
- ClientCRC: cliCRC,
- ServerCRC: srvCRC,
- }, nil
+ if strings.EqualFold(resp.Request.Method, "GET") {
+ return true
+ }
+ return false
}
// LoggerHTTPReq Print the header information of the http request
@@ -680,9 +863,10 @@ func (c *timeoutConn) SetWriteDeadline(t time.Time) error {
// UrlMaker builds URL and resource
const (
- urlTypeCname = 1
- urlTypeIP = 2
- urlTypeAliyun = 3
+ urlTypeCname = 1
+ urlTypeIP = 2
+ urlTypeAliyun = 3
+ urlTypePathStyle = 4
)
type urlMaker struct {
@@ -694,6 +878,11 @@ type urlMaker struct {
// Init parses endpoint
func (um *urlMaker) Init(endpoint string, isCname bool, isProxy bool) error {
+ return um.InitExt(endpoint, isCname, isProxy, false)
+}
+
+// InitExt parses endpoint
+func (um *urlMaker) InitExt(endpoint string, isCname bool, isProxy bool, isPathStyle bool) error {
if strings.HasPrefix(endpoint, "http://") {
um.Scheme = "http"
um.NetLoc = endpoint[len("http://"):]
@@ -716,7 +905,7 @@ func (um *urlMaker) Init(endpoint string, isCname bool, isProxy bool) error {
host, _, err := net.SplitHostPort(um.NetLoc)
if err != nil {
host = um.NetLoc
- if host[0] == '[' && host[len(host)-1] == ']' {
+ if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' {
host = host[1 : len(host)-1]
}
}
@@ -726,6 +915,8 @@ func (um *urlMaker) Init(endpoint string, isCname bool, isProxy bool) error {
um.Type = urlTypeIP
} else if isCname {
um.Type = urlTypeCname
+ } else if isPathStyle {
+ um.Type = urlTypePathStyle
} else {
um.Type = urlTypeAliyun
}
@@ -774,7 +965,7 @@ func (um urlMaker) buildURL(bucket, object string) (string, string) {
if um.Type == urlTypeCname {
host = um.NetLoc
path = "/" + object
- } else if um.Type == urlTypeIP {
+ } else if um.Type == urlTypeIP || um.Type == urlTypePathStyle {
if bucket == "" {
host = um.NetLoc
path = "/"
@@ -794,3 +985,37 @@ func (um urlMaker) buildURL(bucket, object string) (string, string) {
return host, path
}
+
+// buildURL builds URL
+func (um urlMaker) buildURLV4(bucket, object string) (string, string) {
+ var host = ""
+ var path = ""
+
+ object = url.QueryEscape(object)
+ object = strings.Replace(object, "+", "%20", -1)
+
+ // no escape /
+ object = strings.Replace(object, "%2F", "/", -1)
+
+ if um.Type == urlTypeCname {
+ host = um.NetLoc
+ path = "/" + object
+ } else if um.Type == urlTypeIP || um.Type == urlTypePathStyle {
+ if bucket == "" {
+ host = um.NetLoc
+ path = "/"
+ } else {
+ host = um.NetLoc
+ path = fmt.Sprintf("/%s/%s", bucket, object)
+ }
+ } else {
+ if bucket == "" {
+ host = um.NetLoc
+ path = "/"
+ } else {
+ host = bucket + "." + um.NetLoc
+ path = fmt.Sprintf("/%s/%s", bucket, object)
+ }
+ }
+ return host, path
+}
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/const.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/const.go
index 6e02ef529..400f7cf95 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/const.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/const.go
@@ -76,6 +76,9 @@ const (
// StorageColdArchive cold archive
StorageColdArchive StorageClassType = "ColdArchive"
+
+ // StorageDeepColdArchive deep cold archive
+ StorageDeepColdArchive StorageClassType = "DeepColdArchive"
)
//RedundancyType bucket data Redundancy type
@@ -203,6 +206,12 @@ const (
HTTPHeaderOssTaskID = "X-Oss-Task-Id"
HTTPHeaderOssHashCtx = "X-Oss-Hash-Ctx"
HTTPHeaderOssMd5Ctx = "X-Oss-Md5-Ctx"
+ HTTPHeaderAllowSameActionOverLap = "X-Oss-Allow-Same-Action-Overlap"
+ HttpHeaderOssDate = "X-Oss-Date"
+ HttpHeaderOssContentSha256 = "X-Oss-Content-Sha256"
+ HttpHeaderOssNotification = "X-Oss-Notification"
+ HTTPHeaderOssEc = "X-Oss-Ec"
+ HTTPHeaderOssErr = "X-Oss-Err"
)
// HTTP Param
@@ -218,6 +227,9 @@ const (
HTTPParamAccessKeyIDV2 = "x-oss-access-key-id"
HTTPParamSignatureV2 = "x-oss-signature"
HTTPParamAdditionalHeadersV2 = "x-oss-additional-headers"
+ HTTPParamCredential = "x-oss-credential"
+ HTTPParamDate = "x-oss-date"
+ HTTPParamOssSecurityToken = "x-oss-security-token"
)
// Other constants
@@ -234,7 +246,9 @@ const (
NullVersion = "null"
- Version = "v2.1.8" // Go SDK version
+ DefaultContentSha256 = "UNSIGNED-PAYLOAD" // for v4 signature
+
+ Version = "v3.0.2" // Go SDK version
)
// FrameType
@@ -254,4 +268,6 @@ const (
AuthV1 AuthVersionType = "v1"
// AuthV2 v2
AuthV2 AuthVersionType = "v2"
+ // AuthV4 v4
+ AuthV4 AuthVersionType = "v4"
)
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/error.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/error.go
index a877211fa..aaa24f28a 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/error.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/error.go
@@ -3,7 +3,9 @@ package oss
import (
"encoding/xml"
"fmt"
+ "io/ioutil"
"net/http"
+ "strconv"
"strings"
)
@@ -15,18 +17,22 @@ type ServiceError struct {
RequestID string `xml:"RequestId"` // The UUID used to uniquely identify the request
HostID string `xml:"HostId"` // The OSS server cluster's Id
Endpoint string `xml:"Endpoint"`
+ Ec string `xml:"EC"`
RawMessage string // The raw messages from OSS
StatusCode int // HTTP status code
+
}
// Error implements interface error
func (e ServiceError) Error() string {
- if e.Endpoint == "" {
- return fmt.Sprintf("oss: service returned error: StatusCode=%d, ErrorCode=%s, ErrorMessage=\"%s\", RequestId=%s",
- e.StatusCode, e.Code, e.Message, e.RequestID)
+ errorStr := fmt.Sprintf("oss: service returned error: StatusCode=%d, ErrorCode=%s, ErrorMessage=\"%s\", RequestId=%s", e.StatusCode, e.Code, e.Message, e.RequestID)
+ if len(e.Endpoint) > 0 {
+ errorStr = fmt.Sprintf("%s, Endpoint=%s", errorStr, e.Endpoint)
+ }
+ if len(e.Ec) > 0 {
+ errorStr = fmt.Sprintf("%s, Ec=%s", errorStr, e.Ec)
}
- return fmt.Sprintf("oss: service returned error: StatusCode=%d, ErrorCode=%s, ErrorMessage=\"%s\", RequestId=%s, Endpoint=%s",
- e.StatusCode, e.Code, e.Message, e.RequestID, e.Endpoint)
+ return errorStr
}
// UnexpectedStatusCodeError is returned when a storage service responds with neither an error
@@ -65,6 +71,42 @@ func CheckRespCode(respCode int, allowed []int) error {
return UnexpectedStatusCodeError{allowed, respCode}
}
+// CheckCallbackResp return error if the given response code is not 200
+func CheckCallbackResp(resp *Response) error {
+ var err error
+ contentLengthStr := resp.Headers.Get("Content-Length")
+ contentLength, _ := strconv.Atoi(contentLengthStr)
+ var bodyBytes []byte
+ if contentLength > 0 {
+ bodyBytes, _ = ioutil.ReadAll(resp.Body)
+ }
+ if len(bodyBytes) > 0 {
+ srvErr, errIn := serviceErrFromXML(bodyBytes, resp.StatusCode,
+ resp.Headers.Get(HTTPHeaderOssRequestID))
+ if errIn != nil {
+ if len(resp.Headers.Get(HTTPHeaderOssEc)) > 0 {
+ err = fmt.Errorf("unknown response body, status code = %d, RequestId = %s, ec = %s", resp.StatusCode, resp.Headers.Get(HTTPHeaderOssRequestID), resp.Headers.Get(HTTPHeaderOssEc))
+ } else {
+ err = fmt.Errorf("unknown response body, status code= %d, RequestId = %s", resp.StatusCode, resp.Headers.Get(HTTPHeaderOssRequestID))
+ }
+ } else {
+ err = srvErr
+ }
+ }
+ return err
+}
+
+func tryConvertServiceError(data []byte, resp *Response, def error) (err error) {
+ err = def
+ if len(data) > 0 {
+ srvErr, errIn := serviceErrFromXML(data, resp.StatusCode, resp.Headers.Get(HTTPHeaderOssRequestID))
+ if errIn == nil {
+ err = srvErr
+ }
+ }
+ return err
+}
+
// CRCCheckError is returned when crc check is inconsistent between client and server
type CRCCheckError struct {
clientCRC uint64 // Calculated CRC64 in client
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/limit_reader_1_6.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/limit_reader_1_6.go
index 943dc8fd0..2293f9904 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/limit_reader_1_6.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/limit_reader_1_6.go
@@ -1,3 +1,4 @@
+//go:build !go1.7
// +build !go1.7
// "golang.org/x/time/rate" is depended on golang context package go1.7 onward
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/limit_reader_1_7.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/limit_reader_1_7.go
index f6baf2987..ea0826cec 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/limit_reader_1_7.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/limit_reader_1_7.go
@@ -1,3 +1,4 @@
+//go:build go1.7
// +build go1.7
package oss
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/livechannel.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/livechannel.go
index bf5ba070b..1fd30fdfd 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/livechannel.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/livechannel.go
@@ -203,7 +203,7 @@ func (bucket Bucket) ListLiveChannel(options ...Option) (ListLiveChannelResult,
params["live"] = nil
- resp, err := bucket.do("GET", "", params, nil, nil, nil)
+ resp, err := bucket.doInner("GET", "", params, nil, nil, nil)
if err != nil {
return out, err
}
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/mime.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/mime.go
index 64f4dcc63..96a9ee7aa 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/mime.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/mime.go
@@ -567,6 +567,28 @@ func TypeByExtension(filePath string) string {
typ := mime.TypeByExtension(path.Ext(filePath))
if typ == "" {
typ = extToMimeType[strings.ToLower(path.Ext(filePath))]
+ } else {
+ if strings.HasPrefix(typ, "text/") && strings.Contains(typ, "charset=") {
+ typ = removeCharsetInMimeType(typ)
+ }
}
return typ
}
+
+// Remove charset from mime type
+func removeCharsetInMimeType(typ string) (str string) {
+ temArr := strings.Split(typ, ";")
+ var builder strings.Builder
+ for i, s := range temArr {
+ tmpStr := strings.Trim(s, " ")
+ if strings.Contains(tmpStr, "charset=") {
+ continue
+ }
+ if i == 0 {
+ builder.WriteString(s)
+ } else {
+ builder.WriteString("; " + s)
+ }
+ }
+ return builder.String()
+}
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/multipart.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/multipart.go
index 9e7141971..aea7fafb6 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/multipart.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/multipart.go
@@ -4,6 +4,7 @@ import (
"bytes"
"encoding/xml"
"io"
+ "io/ioutil"
"net/http"
"net/url"
"os"
@@ -15,12 +16,12 @@ import (
//
// objectKey object name
// options the object constricts for upload. The valid options are CacheControl, ContentDisposition, ContentEncoding, Expires,
-// ServerSideEncryption, Meta, check out the following link:
-// https://help.aliyun.com/document_detail/oss/api-reference/multipart-upload/InitiateMultipartUpload.html
+//
+// ServerSideEncryption, Meta, check out the following link:
+// https://www.alibabacloud.com/help/en/object-storage-service/latest/initiatemultipartupload
//
// InitiateMultipartUploadResult the return value of the InitiateMultipartUpload, which is used for calls later on such as UploadPartFromFile,UploadPartCopy.
// error it's nil if the operation succeeds, otherwise it's an error object.
-//
func (bucket Bucket) InitiateMultipartUpload(objectKey string, options ...Option) (InitiateMultipartUploadResult, error) {
var imur InitiateMultipartUploadResult
opts := AddContentType(options, objectKey)
@@ -53,7 +54,6 @@ func (bucket Bucket) InitiateMultipartUpload(objectKey string, options ...Option
//
// UploadPart the return value of the upload part. It consists of PartNumber and ETag. It's valid when error is nil.
// error it's nil if the operation succeeds, otherwise it's an error object.
-//
func (bucket Bucket) UploadPart(imur InitiateMultipartUploadResult, reader io.Reader,
partSize int64, partNumber int, options ...Option) (UploadPart, error) {
request := &UploadPartRequest{
@@ -78,7 +78,6 @@ func (bucket Bucket) UploadPart(imur InitiateMultipartUploadResult, reader io.Re
//
// UploadPart the return value consists of PartNumber and ETag.
// error it's nil if the operation succeeds, otherwise it's an error object.
-//
func (bucket Bucket) UploadPartFromFile(imur InitiateMultipartUploadResult, filePath string,
startPosition, partSize int64, partNumber int, options ...Option) (UploadPart, error) {
var part = UploadPart{}
@@ -107,7 +106,6 @@ func (bucket Bucket) UploadPartFromFile(imur InitiateMultipartUploadResult, file
//
// UploadPartResult the result of uploading part.
// error it's nil if the operation succeeds, otherwise it's an error object.
-//
func (bucket Bucket) DoUploadPart(request *UploadPartRequest, options []Option) (*UploadPartResult, error) {
listener := GetProgressListener(options)
options = append(options, ContentLength(request.PartSize))
@@ -144,12 +142,12 @@ func (bucket Bucket) DoUploadPart(request *UploadPartRequest, options []Option)
// partSize the part size
// partNumber the part number, ranges from 1 to 10,000. If it exceeds the range OSS returns InvalidArgument error.
// options the constraints of source object for the copy. The copy happens only when these contraints are met. Otherwise it returns error.
-// CopySourceIfNoneMatch, CopySourceIfModifiedSince CopySourceIfUnmodifiedSince, check out the following link for the detail
-// https://help.aliyun.com/document_detail/oss/api-reference/multipart-upload/UploadPartCopy.html
+//
+// CopySourceIfNoneMatch, CopySourceIfModifiedSince CopySourceIfUnmodifiedSince, check out the following link for the detail
+// https://www.alibabacloud.com/help/en/object-storage-service/latest/uploadpartcopy
//
// UploadPart the return value consists of PartNumber and ETag.
// error it's nil if the operation succeeds, otherwise it's an error object.
-//
func (bucket Bucket) UploadPartCopy(imur InitiateMultipartUploadResult, srcBucketName, srcObjectKey string,
startPosition, partSize int64, partNumber int, options ...Option) (UploadPart, error) {
var out UploadPartCopyResult
@@ -196,7 +194,6 @@ func (bucket Bucket) UploadPartCopy(imur InitiateMultipartUploadResult, srcBucke
//
// CompleteMultipartUploadResponse the return value when the call succeeds. Only valid when the error is nil.
// error it's nil if the operation succeeds, otherwise it's an error object.
-//
func (bucket Bucket) CompleteMultipartUpload(imur InitiateMultipartUploadResult,
parts []UploadPart, options ...Option) (CompleteMultipartUploadResult, error) {
var out CompleteMultipartUploadResult
@@ -218,8 +215,28 @@ func (bucket Bucket) CompleteMultipartUpload(imur InitiateMultipartUploadResult,
return out, err
}
defer resp.Body.Close()
-
- err = xmlUnmarshal(resp.Body, &out)
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return out, err
+ }
+ err = CheckRespCode(resp.StatusCode, []int{http.StatusOK})
+ if len(body) > 0 {
+ if err != nil {
+ err = tryConvertServiceError(body, resp, err)
+ } else {
+ callback, _ := FindOption(options, HTTPHeaderOssCallback, nil)
+ if callback == nil {
+ err = xml.Unmarshal(body, &out)
+ } else {
+ rb, _ := FindOption(options, responseBody, nil)
+ if rb != nil {
+ if rbody, ok := rb.(*[]byte); ok {
+ *rbody = body
+ }
+ }
+ }
+ }
+ }
return out, err
}
@@ -228,7 +245,6 @@ func (bucket Bucket) CompleteMultipartUpload(imur InitiateMultipartUploadResult,
// imur the return value of InitiateMultipartUpload.
//
// error it's nil if the operation succeeds, otherwise it's an error object.
-//
func (bucket Bucket) AbortMultipartUpload(imur InitiateMultipartUploadResult, options ...Option) error {
params := map[string]interface{}{}
params["uploadId"] = imur.UploadID
@@ -246,7 +262,6 @@ func (bucket Bucket) AbortMultipartUpload(imur InitiateMultipartUploadResult, op
//
// ListUploadedPartsResponse the return value if it succeeds, only valid when error is nil.
// error it's nil if the operation succeeds, otherwise it's an error object.
-//
func (bucket Bucket) ListUploadedParts(imur InitiateMultipartUploadResult, options ...Option) (ListUploadedPartsResult, error) {
var out ListUploadedPartsResult
options = append(options, EncodingType("url"))
@@ -275,11 +290,11 @@ func (bucket Bucket) ListUploadedParts(imur InitiateMultipartUploadResult, optio
// ListMultipartUploads lists all ongoing multipart upload tasks
//
// options listObject's filter. Prefix specifies the returned object's prefix; KeyMarker specifies the returned object's start point in lexicographic order;
-// MaxKeys specifies the max entries to return; Delimiter is the character for grouping object keys.
+//
+// MaxKeys specifies the max entries to return; Delimiter is the character for grouping object keys.
//
// ListMultipartUploadResponse the return value if it succeeds, only valid when error is nil.
// error it's nil if the operation succeeds, otherwise it's an error object.
-//
func (bucket Bucket) ListMultipartUploads(options ...Option) (ListMultipartUploadResult, error) {
var out ListMultipartUploadResult
@@ -290,7 +305,7 @@ func (bucket Bucket) ListMultipartUploads(options ...Option) (ListMultipartUploa
}
params["uploads"] = nil
- resp, err := bucket.do("GET", "", params, options, nil, nil)
+ resp, err := bucket.doInner("GET", "", params, options, nil, nil)
if err != nil {
return out, err
}
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/option.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/option.go
index a8d5dc39d..7e517ddbe 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/option.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/option.go
@@ -1,7 +1,9 @@
package oss
import (
+ "context"
"fmt"
+ "io/ioutil"
"net/http"
"net/url"
"strconv"
@@ -12,9 +14,11 @@ import (
type optionType string
const (
- optionParam optionType = "HTTPParameter" // URL parameter
- optionHTTP optionType = "HTTPHeader" // HTTP header
- optionArg optionType = "FuncArgument" // Function argument
+ optionParam optionType = "HTTPParameter" // URL parameter
+ optionHTTP optionType = "HTTPHeader" // HTTP header
+ optionContext optionType = "HTTPContext" // context
+ optionArg optionType = "FuncArgument" // Function argument
+
)
const (
@@ -27,6 +31,8 @@ const (
responseHeader = "x-response-header"
redundancyType = "redundancy-type"
objectHashFunc = "object-hash-func"
+ responseBody = "x-response-body"
+ contextArg = "x-context-arg"
)
type (
@@ -448,6 +454,11 @@ func ObjectHashFunc(value ObjecthashFuncType) Option {
return addArg(objectHashFunc, value)
}
+// WithContext returns an option that sets the context for requests.
+func WithContext(ctx context.Context) Option {
+ return addArg(contextArg, ctx)
+}
+
// Checkpoint configuration
type cpConfig struct {
IsEnable bool
@@ -485,6 +496,11 @@ func GetResponseHeader(respHeader *http.Header) Option {
return addArg(responseHeader, respHeader)
}
+// CallbackResult for get response of call back
+func CallbackResult(body *[]byte) Option {
+ return addArg(responseBody, body)
+}
+
// ResponseContentType is an option to set response-content-type param
func ResponseContentType(value string) Option {
return addParam("response-content-type", value)
@@ -678,3 +694,42 @@ func GetDeleteMark(header http.Header) bool {
func GetQosDelayTime(header http.Header) string {
return header.Get("x-oss-qos-delay-time")
}
+
+// ForbidOverWrite is an option to set X-Oss-Forbid-Overwrite
+func AllowSameActionOverLap(enabled bool) Option {
+ if enabled {
+ return setHeader(HTTPHeaderAllowSameActionOverLap, "true")
+ } else {
+ return setHeader(HTTPHeaderAllowSameActionOverLap, "false")
+ }
+}
+
+func GetCallbackBody(options []Option, resp *Response, callbackSet bool) error {
+ var err error
+
+ // get response body
+ if callbackSet {
+ err = setBody(options, resp)
+ } else {
+ callback, _ := FindOption(options, HTTPHeaderOssCallback, nil)
+ if callback != nil {
+ err = setBody(options, resp)
+ }
+ }
+ return err
+}
+
+func setBody(options []Option, resp *Response) error {
+ respBody, _ := FindOption(options, responseBody, nil)
+ if respBody != nil && resp != nil {
+ pRespBody := respBody.(*[]byte)
+ pBody, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return err
+ }
+ if pBody != nil {
+ *pRespBody = pBody
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/progress.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/progress.go
index 9f3aa9f61..1b6535ba5 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/progress.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/progress.go
@@ -10,7 +10,7 @@ type ProgressEventType int
const (
// TransferStartedEvent transfer started, set TotalBytes
TransferStartedEvent ProgressEventType = 1 + iota
- // TransferDataEvent transfer data, set ConsumedBytes anmd TotalBytes
+ // TransferDataEvent transfer data, set ConsumedBytes and TotalBytes
TransferDataEvent
// TransferCompletedEvent transfer completed
TransferCompletedEvent
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/redirect_1_6.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/redirect_1_6.go
index d09bc5ebd..ea17d5bd5 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/redirect_1_6.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/redirect_1_6.go
@@ -1,3 +1,4 @@
+//go:build !go1.7
// +build !go1.7
package oss
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/redirect_1_7.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/redirect_1_7.go
index 5b0bb8674..5d1442dd1 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/redirect_1_7.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/redirect_1_7.go
@@ -1,3 +1,4 @@
+//go:build go1.7
// +build go1.7
package oss
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/select_object_type.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/select_object_type.go
index 8b75782f3..75a454555 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/select_object_type.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/select_object_type.go
@@ -107,6 +107,7 @@ func (sr *SelectObjectResponse) readFrames(p []byte) (int, error) {
if err != nil || !checkValid {
return nn, fmt.Errorf("%s", err.Error())
}
+ sr.Frame.OpenLine = false
} else if sr.Frame.FrameType == EndFrameType {
err = sr.analysisEndFrame()
if err != nil {
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/transport_1_6.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/transport_1_6.go
index 795ca8bb3..08a83a001 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/transport_1_6.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/transport_1_6.go
@@ -1,8 +1,10 @@
+//go:build !go1.7
// +build !go1.7
package oss
import (
+ "crypto/tls"
"net"
"net/http"
"time"
@@ -30,5 +32,11 @@ func newTransport(conn *Conn, config *Config) *http.Transport {
MaxIdleConnsPerHost: httpMaxConns.MaxIdleConnsPerHost,
ResponseHeaderTimeout: httpTimeOut.HeaderTimeout,
}
+
+ if config.InsecureSkipVerify {
+ transport.TLSClientConfig = &tls.Config{
+ InsecureSkipVerify: true,
+ }
+ }
return transport
}
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/transport_1_7.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/transport_1_7.go
index 757543bc4..1acb84154 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/transport_1_7.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/transport_1_7.go
@@ -1,8 +1,10 @@
+//go:build go1.7
// +build go1.7
package oss
import (
+ "crypto/tls"
"net"
"net/http"
"time"
@@ -29,8 +31,15 @@ func newTransport(conn *Conn, config *Config) *http.Transport {
},
MaxIdleConns: httpMaxConns.MaxIdleConns,
MaxIdleConnsPerHost: httpMaxConns.MaxIdleConnsPerHost,
+ MaxConnsPerHost: httpMaxConns.MaxConnsPerHost,
IdleConnTimeout: httpTimeOut.IdleConnTimeout,
ResponseHeaderTimeout: httpTimeOut.HeaderTimeout,
}
+
+ if config.InsecureSkipVerify {
+ transport.TLSClientConfig = &tls.Config{
+ InsecureSkipVerify: true,
+ }
+ }
return transport
}
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/type.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/type.go
index e80d2db5d..a704e3cef 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/type.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/type.go
@@ -5,6 +5,8 @@ import (
"encoding/xml"
"fmt"
"net/url"
+ "strconv"
+ "strings"
"time"
)
@@ -27,6 +29,29 @@ type BucketProperties struct {
Location string `xml:"Location"` // Bucket datacenter
CreationDate time.Time `xml:"CreationDate"` // Bucket create time
StorageClass string `xml:"StorageClass"` // Bucket storage class
+ Region string `xml:"Region"` // Bucket region
+}
+
+// ListCloudBoxResult defines the result object from ListBuckets request
+type ListCloudBoxResult struct {
+ XMLName xml.Name `xml:"ListCloudBoxResult"`
+ Prefix string `xml:"Prefix"` // The prefix in this query
+ Marker string `xml:"Marker"` // The marker filter
+ MaxKeys int `xml:"MaxKeys"` // The max entry count to return. This information is returned when IsTruncated is true.
+ IsTruncated bool `xml:"IsTruncated"` // Flag true means there's remaining cloudboxes to return.
+ NextMarker string `xml:"NextMarker"` // The marker filter for the next list call
+ Owner string `xml:"Owner>DisplayName"` // The owner information
+ CloudBoxes []CloudBoxProperties `xml:"CloudBoxes>CloudBox"` // The cloudbox list
+}
+
+// CloudBoxProperties defines cloudbox properties
+type CloudBoxProperties struct {
+ XMLName xml.Name `xml:"CloudBox"`
+ ID string `xml:"ID"`
+ Name string `xml:"Name"`
+ Region string `xml:"Region"`
+ ControlEndpoint string `xml:"ControlEndpoint"`
+ DataEndpoint string `xml:"DataEndpoint"`
}
// GetBucketACLResult defines GetBucketACL request's result
@@ -56,6 +81,7 @@ type LifecycleRule struct {
// Deprecated: Use NonVersionTransitions instead.
NonVersionTransition *LifecycleVersionTransition `xml:"-"` // NonVersionTransition is not suggested to use
NonVersionTransitions []LifecycleVersionTransition `xml:"NoncurrentVersionTransition,omitempty"`
+ Filter *LifecycleFilter `xml:Filter,omitempty` //condition parameter container of this exclusion rule
}
// LifecycleExpiration defines the rule's expiration property
@@ -69,10 +95,13 @@ type LifecycleExpiration struct {
// LifecycleTransition defines the rule's transition propery
type LifecycleTransition struct {
- XMLName xml.Name `xml:"Transition"`
- Days int `xml:"Days,omitempty"` // Relative transition time: The transition time in days after the last modified time
- CreatedBeforeDate string `xml:"CreatedBeforeDate,omitempty"` // objects created before the date will be expired
- StorageClass StorageClassType `xml:"StorageClass,omitempty"` // Specifies the target storage type
+ XMLName xml.Name `xml:"Transition"`
+ Days int `xml:"Days,omitempty"` // Relative transition time: The transition time in days after the last modified time
+ CreatedBeforeDate string `xml:"CreatedBeforeDate,omitempty"` // objects created before the date will be expired
+ StorageClass StorageClassType `xml:"StorageClass,omitempty"` // Specifies the target storage type
+ IsAccessTime *bool `xml:"IsAccessTime,omitempty"` // access time
+ ReturnToStdWhenVisit *bool `xml:"ReturnToStdWhenVisit,omitempty"` // Return To Std When Visit
+ AllowSmallFile *bool `xml:AllowSmallFile,omitempty`
}
// LifecycleAbortMultipartUpload defines the rule's abort multipart upload propery
@@ -90,12 +119,31 @@ type LifecycleVersionExpiration struct {
// LifecycleVersionTransition defines the rule's NoncurrentVersionTransition propery
type LifecycleVersionTransition struct {
- XMLName xml.Name `xml:"NoncurrentVersionTransition"`
- NoncurrentDays int `xml:"NoncurrentDays,omitempty"` // How many days after the Object becomes a non-current version
- StorageClass StorageClassType `xml:"StorageClass,omitempty"`
+ XMLName xml.Name `xml:"NoncurrentVersionTransition"`
+ NoncurrentDays int `xml:"NoncurrentDays,omitempty"` // How many days after the Object becomes a non-current version
+ StorageClass StorageClassType `xml:"StorageClass,omitempty"`
+ IsAccessTime *bool `xml:"IsAccessTime,omitempty"` // access time
+ ReturnToStdWhenVisit *bool `xml:"ReturnToStdWhenVisit,omitempty"` // Return To Std When Visit
+ AllowSmallFile *bool `xml:AllowSmallFile,omitempty`
+}
+
+// LifecycleFilter defines the rule's Filter propery
+type LifecycleFilter struct {
+ XMLName xml.Name `xml:"Filter"`
+ Not []LifecycleFilterNot `xml:"Not,omitempty"`
+ ObjectSizeGreaterThan *int64 `xml:"ObjectSizeGreaterThan,omitempty"`
+ ObjectSizeLessThan *int64 `xml:"ObjectSizeLessThan,omitempty"`
+}
+
+// LifecycleFilterNot defines the rule's Filter Not propery
+type LifecycleFilterNot struct {
+ XMLName xml.Name `xml:"Not"`
+ Prefix string `xml:"Prefix"` //Object prefix applicable to this exclusion rule
+ Tag *Tag `xml:"Tag,omitempty"` //the tags applicable to this exclusion rule
}
const iso8601DateFormat = "2006-01-02T15:04:05.000Z"
+const iso8601DateFormatSecond = "2006-01-02T15:04:05Z"
// BuildLifecycleRuleByDays builds a lifecycle rule objects will expiration in days after the last modified time
func BuildLifecycleRuleByDays(id, prefix string, status bool, days int) LifecycleRule {
@@ -161,14 +209,20 @@ type GetBucketLifecycleResult LifecycleConfiguration
// RefererXML defines Referer configuration
type RefererXML struct {
- XMLName xml.Name `xml:"RefererConfiguration"`
- AllowEmptyReferer bool `xml:"AllowEmptyReferer"` // Allow empty referrer
- RefererList []string `xml:"RefererList>Referer"` // Referer whitelist
+ XMLName xml.Name `xml:"RefererConfiguration"`
+ AllowEmptyReferer bool `xml:"AllowEmptyReferer"` // Allow empty referrer
+ AllowTruncateQueryString *bool `xml:"AllowTruncateQueryString,omitempty"`
+ RefererList []string `xml:"RefererList>Referer"` // Referer whitelist
+ RefererBlacklist *RefererBlacklist `xml:"RefererBlacklist,omitempty"` // Referer blacklist
}
// GetBucketRefererResult defines result object for GetBucketReferer request
type GetBucketRefererResult RefererXML
+type RefererBlacklist struct {
+ Referer []string `xml:"Referer,omitempty"`
+}
+
// LoggingXML defines logging configuration
type LoggingXML struct {
XMLName xml.Name `xml:"BucketLoggingStatus"`
@@ -271,8 +325,9 @@ type GetBucketWebsiteResult WebsiteXML
// CORSXML defines CORS configuration
type CORSXML struct {
- XMLName xml.Name `xml:"CORSConfiguration"`
- CORSRules []CORSRule `xml:"CORSRule"` // CORS rules
+ XMLName xml.Name `xml:"CORSConfiguration"`
+ CORSRules []CORSRule `xml:"CORSRule"` // CORS rules
+ ResponseVary *bool `xml:"ResponseVary,omitempty"` // return Vary or not
}
// CORSRule defines CORS rules
@@ -288,6 +343,9 @@ type CORSRule struct {
// GetBucketCORSResult defines the result from GetBucketCORS request.
type GetBucketCORSResult CORSXML
+// PutBucketCORS defines the PutBucketCORS config xml.
+type PutBucketCORS CORSXML
+
// GetBucketInfoResult defines the result from GetBucketInfo request.
type GetBucketInfoResult struct {
XMLName xml.Name `xml:"BucketInfo"`
@@ -296,18 +354,21 @@ type GetBucketInfoResult struct {
// BucketInfo defines Bucket information
type BucketInfo struct {
- XMLName xml.Name `xml:"Bucket"`
- Name string `xml:"Name"` // Bucket name
- Location string `xml:"Location"` // Bucket datacenter
- CreationDate time.Time `xml:"CreationDate"` // Bucket creation time
- ExtranetEndpoint string `xml:"ExtranetEndpoint"` // Bucket external endpoint
- IntranetEndpoint string `xml:"IntranetEndpoint"` // Bucket internal endpoint
- ACL string `xml:"AccessControlList>Grant"` // Bucket ACL
- RedundancyType string `xml:"DataRedundancyType"` // Bucket DataRedundancyType
- Owner Owner `xml:"Owner"` // Bucket owner
- StorageClass string `xml:"StorageClass"` // Bucket storage class
- SseRule SSERule `xml:"ServerSideEncryptionRule"` // Bucket ServerSideEncryptionRule
- Versioning string `xml:"Versioning"` // Bucket Versioning
+ XMLName xml.Name `xml:"Bucket"`
+ Name string `xml:"Name"` // Bucket name
+ AccessMonitor string `xml:"AccessMonitor"` // Bucket Access Monitor
+ Location string `xml:"Location"` // Bucket datacenter
+ CreationDate time.Time `xml:"CreationDate"` // Bucket creation time
+ ExtranetEndpoint string `xml:"ExtranetEndpoint"` // Bucket external endpoint
+ IntranetEndpoint string `xml:"IntranetEndpoint"` // Bucket internal endpoint
+ ACL string `xml:"AccessControlList>Grant"` // Bucket ACL
+ RedundancyType string `xml:"DataRedundancyType"` // Bucket DataRedundancyType
+ Owner Owner `xml:"Owner"` // Bucket owner
+ StorageClass string `xml:"StorageClass"` // Bucket storage class
+ SseRule SSERule `xml:"ServerSideEncryptionRule"` // Bucket ServerSideEncryptionRule
+ Versioning string `xml:"Versioning"` // Bucket Versioning
+ TransferAcceleration string `xml:"TransferAcceleration"` // bucket TransferAcceleration
+ CrossRegionReplication string `xml:"CrossRegionReplication"` // bucket CrossRegionReplication
}
type SSERule struct {
@@ -333,13 +394,14 @@ type ListObjectsResult struct {
// ObjectProperties defines Objecct properties
type ObjectProperties struct {
XMLName xml.Name `xml:"Contents"`
- Key string `xml:"Key"` // Object key
- Type string `xml:"Type"` // Object type
- Size int64 `xml:"Size"` // Object size
- ETag string `xml:"ETag"` // Object ETag
- Owner Owner `xml:"Owner"` // Object owner information
- LastModified time.Time `xml:"LastModified"` // Object last modified time
- StorageClass string `xml:"StorageClass"` // Object storage class (Standard, IA, Archive)
+ Key string `xml:"Key"` // Object key
+ Type string `xml:"Type"` // Object type
+ Size int64 `xml:"Size"` // Object size
+ ETag string `xml:"ETag"` // Object ETag
+ Owner Owner `xml:"Owner"` // Object owner information
+ LastModified time.Time `xml:"LastModified"` // Object last modified time
+ StorageClass string `xml:"StorageClass"` // Object storage class (Standard, IA, Archive)
+ RestoreInfo string `xml:"RestoreInfo,omitempty"` // Object restoreInfo
}
// ListObjectsResultV2 defines the result from ListObjectsV2 request
@@ -385,15 +447,16 @@ type ObjectDeleteMarkerProperties struct {
type ObjectVersionProperties struct {
XMLName xml.Name `xml:"Version"`
- Key string `xml:"Key"` // The Object Key
- VersionId string `xml:"VersionId"` // The Object VersionId
- IsLatest bool `xml:"IsLatest"` // is latest version or not
- LastModified time.Time `xml:"LastModified"` // Object last modified time
- Type string `xml:"Type"` // Object type
- Size int64 `xml:"Size"` // Object size
- ETag string `xml:"ETag"` // Object ETag
- StorageClass string `xml:"StorageClass"` // Object storage class (Standard, IA, Archive)
- Owner Owner `xml:"Owner"` // bucket owner element
+ Key string `xml:"Key"` // The Object Key
+ VersionId string `xml:"VersionId"` // The Object VersionId
+ IsLatest bool `xml:"IsLatest"` // is latest version or not
+ LastModified time.Time `xml:"LastModified"` // Object last modified time
+ Type string `xml:"Type"` // Object type
+ Size int64 `xml:"Size"` // Object size
+ ETag string `xml:"ETag"` // Object ETag
+ StorageClass string `xml:"StorageClass"` // Object storage class (Standard, IA, Archive)
+ Owner Owner `xml:"Owner"` // bucket owner element
+ RestoreInfo string `xml:"RestoreInfo,omitempty"` // Object restoreInfo
}
// Owner defines Bucket/Object's owner
@@ -432,13 +495,13 @@ type DeleteObjectsResult struct {
DeletedObjects []string // Deleted object key list
}
-// DeleteObjectsResult_inner defines result of DeleteObjects request
+// DeleteObjectVersionsResult defines result of DeleteObjects request
type DeleteObjectVersionsResult struct {
XMLName xml.Name `xml:"DeleteResult"`
DeletedObjectsDetail []DeletedKeyInfo `xml:"Deleted"` // Deleted object detail info
}
-// DeleteKeyInfo defines object delete info
+// DeletedKeyInfo defines object delete info
type DeletedKeyInfo struct {
XMLName xml.Name `xml:"Deleted"`
Key string `xml:"Key"` // Object key
@@ -550,6 +613,13 @@ type ProcessObjectResult struct {
Status string `json:"status"`
}
+// AsyncProcessObjectResult defines result object of AsyncProcessObject
+type AsyncProcessObjectResult struct {
+ EventId string `json:"EventId"`
+ RequestId string `json:"RequestId"`
+ TaskId string `json:"TaskId"`
+}
+
// decodeDeleteObjectsResult decodes deleting objects result in URL encoding
func decodeDeleteObjectsResult(result *DeleteObjectVersionsResult) error {
var err error
@@ -741,6 +811,33 @@ func decodeListMultipartUploadResult(result *ListMultipartUploadResult) error {
return nil
}
+// marshalDeleteObjectToXml deleteXML struct to xml
+func marshalDeleteObjectToXml(dxml deleteXML) string {
+ var builder strings.Builder
+ builder.WriteString("")
+ builder.WriteString("")
+ builder.WriteString(strconv.FormatBool(dxml.Quiet))
+ builder.WriteString("")
+ if len(dxml.Objects) > 0 {
+ for _, object := range dxml.Objects {
+ builder.WriteString("")
+ }
+ }
+ builder.WriteString("")
+ return builder.String()
+}
+
// createBucketConfiguration defines the configuration for creating a bucket.
type createBucketConfiguration struct {
XMLName xml.Name `xml:"CreateBucketConfiguration"`
@@ -854,13 +951,13 @@ type Tag struct {
Value string `xml:"Value"`
}
-// Tagging tagset for the object
+// Tagging tag set for the object
type Tagging struct {
XMLName xml.Name `xml:"Tagging"`
Tags []Tag `xml:"TagSet>Tag,omitempty"`
}
-// for GetObjectTagging return value
+// GetObjectTaggingResult for GetObjectTagging return value
type GetObjectTaggingResult Tagging
// VersioningConfig for the bucket
@@ -871,13 +968,13 @@ type VersioningConfig struct {
type GetBucketVersioningResult VersioningConfig
-// Server Encryption rule for the bucket
+// ServerEncryptionRule Server Encryption rule for the bucket
type ServerEncryptionRule struct {
XMLName xml.Name `xml:"ServerSideEncryptionRule"`
SSEDefault SSEDefaultRule `xml:"ApplyServerSideEncryptionByDefault"`
}
-// Server Encryption deafult rule for the bucket
+// SSEDefaultRule Server Encryption deafult rule for the bucket
type SSEDefaultRule struct {
XMLName xml.Name `xml:"ApplyServerSideEncryptionByDefault"`
SSEAlgorithm string `xml:"SSEAlgorithm,omitempty"`
@@ -889,10 +986,23 @@ type GetBucketEncryptionResult ServerEncryptionRule
type GetBucketTaggingResult Tagging
type BucketStat struct {
- XMLName xml.Name `xml:"BucketStat"`
- Storage int64 `xml:"Storage"`
- ObjectCount int64 `xml:"ObjectCount"`
- MultipartUploadCount int64 `xml:"MultipartUploadCount"`
+ XMLName xml.Name `xml:"BucketStat"`
+ Storage int64 `xml:"Storage"`
+ ObjectCount int64 `xml:"ObjectCount"`
+ MultipartUploadCount int64 `xml:"MultipartUploadCount"`
+ LiveChannelCount int64 `xml:"LiveChannelCount"`
+ LastModifiedTime int64 `xml:"LastModifiedTime"`
+ StandardStorage int64 `xml:"StandardStorage"`
+ StandardObjectCount int64 `xml:"StandardObjectCount"`
+ InfrequentAccessStorage int64 `xml:"InfrequentAccessStorage"`
+ InfrequentAccessRealStorage int64 `xml:"InfrequentAccessRealStorage"`
+ InfrequentAccessObjectCount int64 `xml:"InfrequentAccessObjectCount"`
+ ArchiveStorage int64 `xml:"ArchiveStorage"`
+ ArchiveRealStorage int64 `xml:"ArchiveRealStorage"`
+ ArchiveObjectCount int64 `xml:"ArchiveObjectCount"`
+ ColdArchiveStorage int64 `xml:"ColdArchiveStorage"`
+ ColdArchiveRealStorage int64 `xml:"ColdArchiveRealStorage"`
+ ColdArchiveObjectCount int64 `xml:"ColdArchiveObjectCount"`
}
type GetBucketStatResult BucketStat
@@ -1075,7 +1185,7 @@ func (selectReq *SelectRequest) jsonEncodeBase64() {
}
}
-// CsvOptions is a element in the SelectObject api request's params
+// SelectOptions is a element in the SelectObject api request's params
type SelectOptions struct {
XMLName xml.Name `xml:"Options"`
SkipPartialDataRecord *bool `xml:"SkipPartialDataRecord,omitempty"`
@@ -1252,3 +1362,334 @@ type TransferAccConfiguration struct {
XMLName xml.Name `xml:"TransferAccelerationConfiguration"`
Enabled bool `xml:"Enabled"`
}
+
+// ReplicationXML defines simple replication xml, and ReplicationXML is used for "DeleteBucketReplication" in client.go
+type ReplicationXML struct {
+ XMLName xml.Name `xml:"ReplicationRules"`
+ ID string `xml:"ID,omitempty"`
+}
+
+// PutBucketReplication define the bucket replication config
+type PutBucketReplication BucketReplicationXml
+
+// GetBucketReplicationResult define get bucket's replication config
+type GetBucketReplicationResult BucketReplicationXml
+
+// GetBucketReplicationLocationResult define get bucket's replication location
+type GetBucketReplicationLocationResult BucketReplicationLocationXml
+
+// GetBucketReplicationProgressResult define get bucket's replication progress
+type GetBucketReplicationProgressResult BucketReplicationProgressXml
+
+// PutBucketRTC define the bucket rtc config
+type PutBucketRTC BucketRTCXml
+
+// BucketReplicationXml define the xml of bucket replication config
+type BucketReplicationXml struct {
+ XMLName xml.Name `xml:"ReplicationConfiguration"`
+ Rule []ReplicationRule `xml:"Rule,omitempty"`
+}
+
+// BucketReplicationProgressXml define the xml of bucket replication config
+type BucketReplicationProgressXml struct {
+ XMLName xml.Name `xml:"ReplicationProgress"`
+ Rule []ReplicationRule `xml:"Rule,omitempty"`
+}
+
+// BucketRTCXml define the xml of bucket rtc config
+type BucketRTCXml struct {
+ XMLName xml.Name `xml:"ReplicationRule"`
+ RTC *string `xml:"RTC>Status,omitempty"`
+ ID string `xml:"ID,omitempty"`
+}
+
+// ReplicationRule define the xml of bucket replication config rule
+type ReplicationRule struct {
+ ID string `xml:"ID,omitempty"`
+ RTC *string `xml:"RTC>Status,omitempty"`
+ PrefixSet *ReplicationRulePrefix `xml:"PrefixSet,omitempty"`
+ Action string `xml:"Action,omitempty"`
+ Destination *ReplicationRuleDestination `xml:"Destination,omitempty"`
+ HistoricalObjectReplication string `xml:"HistoricalObjectReplication,omitempty"`
+ Status string `xml:"Status,omitempty"`
+ SyncRole string `xml:"SyncRole,omitempty"`
+ SourceSelectionCriteria *string `xml:"SourceSelectionCriteria>SseKmsEncryptedObjects>Status,omitempty"`
+ EncryptionConfiguration *string `xml:"EncryptionConfiguration>ReplicaKmsKeyID,omitempty"`
+ Progress *ReplicationRuleProgress `xml:"Progress,omitempty"`
+ HistoricalObject string `xml:"HistoricalObject,omitempty"`
+}
+
+type ReplicationRulePrefix struct {
+ Prefix []*string `xml:"Prefix,omitempty"`
+}
+
+type ReplicationRuleDestination struct {
+ Bucket string `xml:"Bucket,omitempty"`
+ Location string `xml:"Location,omitempty"`
+ TransferType string `xml:"TransferType,omitempty"`
+}
+
+// BucketReplicationLocationXml define the xml of bucket replication location info
+type BucketReplicationLocationXml struct {
+ XMLName xml.Name `xml:"ReplicationLocation"`
+ Location []string `xml:"Location,omitempty"`
+ LocationTransferType []ReplicationLocationTransferType `xml:"LocationTransferTypeConstraint>LocationTransferType,omitempty"`
+ RTCLocation []string `xml:"LocationRTCConstraint>Location,omitempty"`
+}
+
+type ReplicationLocation struct {
+ Location string `xml:"Location,omitempty"`
+}
+
+type ReplicationLocationTransferType struct {
+ Location string `xml:"Location,omitempty"`
+ TransferTypes string `xml:"TransferTypes>Type,omitempty"`
+}
+
+type ReplicationRuleProgress struct {
+ HistoricalObject string `xml:"HistoricalObject,omitempty"`
+ NewObject string `xml:"NewObject,omitempty"`
+}
+
+// CnameConfigurationXML define cname configuration
+type CnameConfigurationXML struct {
+ XMLName xml.Name `xml:"BucketCnameConfiguration"`
+ Domain string `xml:"Cname>Domain"`
+}
+
+type PutBucketCname PutBucketCnameXml
+
+// PutBucketCnameXml define cname configuration
+type PutBucketCnameXml struct {
+ XMLName xml.Name `xml:"BucketCnameConfiguration"`
+ Cname string `xml:"Cname>Domain"`
+ CertificateConfiguration *CertificateConfiguration `xml:"Cname>CertificateConfiguration"`
+}
+
+type CertificateConfiguration struct {
+ CertId string `xml:"CertId,omitempty"`
+ Certificate string `xml:"Certificate,omitempty"`
+ PrivateKey string `xml:"PrivateKey,omitempty"`
+ PreviousCertId string `xml:"PreviousCertId,omitempty"`
+ Force bool `xml:"Force,omitempty"`
+ DeleteCertificate bool `xml:"DeleteCertificate,omitempty"`
+}
+
+// CnameTokenXML define cname token information
+type CnameTokenXML struct {
+ XMLName xml.Name `xml:"CnameToken"`
+ Bucket string `xml:"Bucket,omitempty"`
+ Cname string `xml:"Cname,omitempty"`
+ Token string `xml:"Token,omitempty"`
+ ExpireTime string `xml:"ExpireTime,omitempty"`
+}
+
+// CreateBucketCnameTokenResult defines result object for CreateBucketCnameToken request
+type CreateBucketCnameTokenResult CnameTokenXML
+
+// GetBucketCnameTokenResult defines result object for GetBucketCnameToken request
+type GetBucketCnameTokenResult CnameTokenXML
+
+// GetMetaQueryStatusResult defines result for GetMetaQueryStatus result
+type GetMetaQueryStatusResult GetMetaQueryStatusResultXml
+
+// GetMetaQueryStatusResultXml define get meta query status information
+type GetMetaQueryStatusResultXml struct {
+ XMLName xml.Name `xml:"MetaQueryStatus"`
+ State string `xml:"State"`
+ Phase string `xml:"Phase"`
+ CreateTime string `xml:"CreateTime"`
+ UpdateTime string `xml:"UpdateTime"`
+}
+
+// MetaQuery defines meta query struct
+type MetaQuery struct {
+ XMLName xml.Name `xml:"MetaQuery"`
+ NextToken string `xml:"NextToken,omitempty"`
+ MaxResults int64 `xml:"MaxResults,omitempty"`
+ Query string `xml:"Query"`
+ Sort string `xml:"Sort,omitempty"`
+ Order string `xml:"Order,omitempty"`
+ Aggregations []MetaQueryAggregationRequest `xml:"Aggregations>Aggregation,omitempty"`
+}
+
+// MetaQueryAggregationRequest defines meta query aggregation request
+type MetaQueryAggregationRequest struct {
+ XMLName xml.Name `xml:"Aggregation"`
+ Field string `xml:"Field,omitempty"`
+ Operation string `xml:"Operation,omitempty"`
+}
+
+// MetaQueryAggregationResponse defines meta query aggregation response
+type MetaQueryAggregationResponse struct {
+ XMLName xml.Name `xml:"Aggregation"`
+ Field string `xml:"Field,omitempty"`
+ Operation string `xml:"Operation,omitempty"`
+ Value float64 `xml:"Value,omitempty"`
+ Groups []MetaQueryGroup `xml:"Groups>Group,omitempty"`
+}
+
+// DoMetaQueryResult defines result for DoMetaQuery result
+type DoMetaQueryResult DoMetaQueryResultXml
+
+// DoMetaQueryResultXml defines do meta query information
+type DoMetaQueryResultXml struct {
+ XMLName xml.Name `xml:"MetaQuery"`
+ NextToken string `xml:"NextToken,omitempty"` // next token
+ Files []MetaQueryFile `xml:"Files>File,omitempty"` // file
+ Aggregations []MetaQueryAggregationResponse `xml:"Aggregations>Aggregation,omitempty"'` // Aggregation
+}
+
+// MetaQueryFile defines do meta query result file information
+type MetaQueryFile struct {
+ XMLName xml.Name `xml:"File"`
+ Filename string `xml:"Filename"` //file name
+ Size int64 `xml:"Size"` // file size
+ FileModifiedTime string `xml:"FileModifiedTime"` // file Modified Time
+ OssObjectType string `xml:"OSSObjectType"` // Oss Object Type
+ OssStorageClass string `xml:"OSSStorageClass"` // Oss Storage Class
+ ObjectACL string `xml:"ObjectACL"` // Object Acl
+ ETag string `xml:"ETag"` // ETag
+ OssCRC64 string `xml:"OSSCRC64"` // Oss CRC64
+ OssTaggingCount int64 `xml:"OSSTaggingCount,omitempty"` // Oss Tagging Count
+ OssTagging []MetaQueryTagging `xml:"OSSTagging>Tagging,omitempty"` // Tagging
+ OssUserMeta []MetaQueryUserMeta `xml:"OSSUserMeta>UserMeta,omitempty"` // UserMeta
+ ServerSideEncryption string `xml:"ServerSideEncryption,omitempty"` //Server Side Encryption
+ ServerSideEncryptionCustomerAlgorithm string `xml:"ServerSideEncryptionCustomerAlgorithm,omitempty"` // Server Side Encryption Customer Algorithm
+}
+
+// MetaQueryTagging defines do meta query result tagging information
+type MetaQueryTagging struct {
+ XMLName xml.Name `xml:"Tagging"`
+ Key string `xml:"Key"`
+ Value string `xml:"Value"`
+}
+
+// MetaQueryUserMeta defines do meta query result user meta information
+type MetaQueryUserMeta struct {
+ XMLName xml.Name `xml:"UserMeta"`
+ Key string `xml:"Key"`
+ Value string `xml:"Value"`
+}
+
+// MetaQueryGroup defines do meta query result group information
+type MetaQueryGroup struct {
+ XMLName xml.Name `xml:"Group"`
+ Value string `xml:"Value"`
+ Count int64 `xml:"Count"`
+}
+
+// GetBucketAccessMonitorResult define config for get bucket access monitor
+type GetBucketAccessMonitorResult BucketAccessMonitorXml
+
+// PutBucketAccessMonitor define the xml of bucket access monitor config
+type PutBucketAccessMonitor BucketAccessMonitorXml
+
+// BucketAccessMonitorXml define get bucket access monitor information
+type BucketAccessMonitorXml struct {
+ XMLName xml.Name `xml:"AccessMonitorConfiguration"`
+ Status string `xml:"Status"` // access monitor status
+}
+
+// ListBucketCnameResult define the cname list of the bucket
+type ListBucketCnameResult BucketCnameXml
+
+// BucketCnameXml define get the bucket cname information
+type BucketCnameXml struct {
+ XMLName xml.Name `xml:"ListCnameResult"`
+ Bucket string `xml:"Bucket"`
+ Owner string `xml:"Owner"`
+ Cname []Cname `xml:"Cname"`
+}
+
+// Cname define the cname information
+type Cname struct {
+ Domain string `xml:"Domain"`
+ LastModified string `xml:"LastModified"`
+ Status string `xml:"Status"`
+ Certificate Certificate `xml:"Certificate"`
+}
+
+// Certificate define Details of domain name certificate
+type Certificate struct {
+ Type string `xml:"Type"`
+ CertId string `xml:"CertId"`
+ Status string `xml:"Status"`
+ CreationDate string `xml:"CreationDate"`
+ Fingerprint string `xml:"Fingerprint"`
+ ValidStartDate string `xml:"ValidStartDate"`
+ ValidEndDate string `xml:"ValidEndDate"`
+}
+
+// GetBucketResourceGroupResult define resource group for the bucket
+type GetBucketResourceGroupResult BucketResourceGroupXml
+
+// PutBucketResourceGroup define the xml of bucket's resource group config
+type PutBucketResourceGroup BucketResourceGroupXml
+
+// BucketResourceGroupXml define the information of the bucket's resource group
+type BucketResourceGroupXml struct {
+ XMLName xml.Name `xml:"BucketResourceGroupConfiguration"`
+ ResourceGroupId string `xml:"ResourceGroupId"` // resource groupId
+}
+
+// GetBucketStyleResult define style for the bucket
+type GetBucketStyleResult BucketStyleXml
+
+// GetBucketListStyleResult define the list style for the bucket
+type GetBucketListStyleResult BucketListStyleXml
+
+// BucketListStyleXml define the list style of the bucket
+type BucketListStyleXml struct {
+ XMLName xml.Name `xml:"StyleList"`
+ Style []BucketStyleXml `xml:"Style,omitempty"` // style
+}
+
+// BucketStyleXml define the information of the bucket's style
+type BucketStyleXml struct {
+ XMLName xml.Name `xml:"Style"`
+ Name string `xml:"Name,omitempty"` // style name
+ Content string `xml:"Content"` // style content
+ CreateTime string `xml:"CreateTime,omitempty"` // style create time
+ LastModifyTime string `xml:"LastModifyTime,omitempty"` // style last modify time
+}
+
+// DescribeRegionsResult define get the describe regions result
+type DescribeRegionsResult RegionInfoList
+
+type RegionInfo struct {
+ Region string `xml:"Region"`
+ InternetEndpoint string `xml:"InternetEndpoint"`
+ InternalEndpoint string `xml:"InternalEndpoint"`
+ AccelerateEndpoint string `xml:"AccelerateEndpoint"`
+}
+
+type RegionInfoList struct {
+ XMLName xml.Name `xml:"RegionInfoList"`
+ Regions []RegionInfo `xml:"RegionInfo"`
+}
+
+//PutBucketResponseHeader define the xml of bucket's response header config
+type PutBucketResponseHeader ResponseHeaderXml
+
+//GetBucketResponseHeaderResult define the xml of bucket's response header result
+type GetBucketResponseHeaderResult ResponseHeaderXml
+
+type ResponseHeaderXml struct {
+ XMLName xml.Name `xml:"ResponseHeaderConfiguration"`
+ Rule []ResponseHeaderRule `xml:Rule,omitempty"` // rule
+}
+
+type ResponseHeaderRule struct {
+ Name string `xml:"Name"` // rule name
+ Filters ResponseHeaderRuleFilters `xml:"Filters,omitempty"` // rule filters Operation
+ HideHeaders ResponseHeaderRuleHeaders `xml:"HideHeaders,omitempty"` // rule hide header
+}
+
+type ResponseHeaderRuleFilters struct {
+ Operation []string `xml:"Operation,omitempty"`
+}
+
+type ResponseHeaderRuleHeaders struct {
+ Header []string `xml:"Header,omitempty"`
+}
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/upload.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/upload.go
index 8b3ea09d2..becc6433d 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/upload.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/upload.go
@@ -1,6 +1,7 @@
package oss
import (
+ "bytes"
"crypto/md5"
"encoding/base64"
"encoding/hex"
@@ -256,7 +257,7 @@ func (bucket Bucket) uploadFile(objectKey, filePath string, partSize int64, opti
}
}
- event = newProgressEvent(TransferStartedEvent, completedBytes, totalBytes, 0)
+ event = newProgressEvent(TransferCompletedEvent, completedBytes, totalBytes, 0)
publishProgress(listener, event)
// Complete the multpart upload
@@ -279,6 +280,8 @@ type uploadCheckpoint struct {
ObjectKey string // Key
UploadID string // Upload ID
Parts []cpPart // All parts of the local file
+ CallbackVal string
+ CallbackBody *[]byte
}
type cpStat struct {
@@ -294,7 +297,19 @@ type cpPart struct {
}
// isValid checks if the uploaded data is valid---it's valid when the file is not updated and the checkpoint data is valid.
-func (cp uploadCheckpoint) isValid(filePath string) (bool, error) {
+func (cp uploadCheckpoint) isValid(filePath string,options []Option) (bool, error) {
+
+ callbackVal, _ := FindOption(options, HTTPHeaderOssCallback, "")
+ if callbackVal != "" && cp.CallbackVal != callbackVal {
+ return false, nil
+ }
+ callbackBody, _ := FindOption(options, responseBody, nil)
+ if callbackBody != nil{
+ body, _ := json.Marshal(callbackBody)
+ if bytes.Equal(*cp.CallbackBody, body) {
+ return false, nil
+ }
+ }
// Compare the CP's magic number and MD5.
cpb := cp
cpb.MD5 = ""
@@ -430,6 +445,13 @@ func prepare(cp *uploadCheckpoint, objectKey, filePath string, partSize int64, b
}
cp.FileStat.Size = st.Size()
cp.FileStat.LastModified = st.ModTime()
+ callbackVal, _ := FindOption(options, HTTPHeaderOssCallback, "")
+ cp.CallbackVal = callbackVal.(string)
+ callbackBody, _ := FindOption(options, responseBody, nil)
+ if callbackBody != nil {
+ body, _ := json.Marshal(callbackBody)
+ cp.CallbackBody = &body
+ }
md, err := calcFileMD5(filePath)
if err != nil {
return err
@@ -462,8 +484,12 @@ func prepare(cp *uploadCheckpoint, objectKey, filePath string, partSize int64, b
func complete(cp *uploadCheckpoint, bucket *Bucket, parts []UploadPart, cpFilePath string, options []Option) error {
imur := InitiateMultipartUploadResult{Bucket: bucket.BucketName,
Key: cp.ObjectKey, UploadID: cp.UploadID}
+
_, err := bucket.CompleteMultipartUpload(imur, parts, options...)
if err != nil {
+ if e, ok := err.(ServiceError);ok && (e.StatusCode == 203 || e.StatusCode == 404) {
+ os.Remove(cpFilePath)
+ }
return err
}
os.Remove(cpFilePath)
@@ -485,7 +511,7 @@ func (bucket Bucket) uploadFileWithCp(objectKey, filePath string, partSize int64
}
// Load error or the CP data is invalid.
- valid, err := ucp.isValid(filePath)
+ valid, err := ucp.isValid(filePath,options)
if err != nil || !valid {
if err = prepare(&ucp, objectKey, filePath, partSize, &bucket, options); err != nil {
return err
diff --git a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/utils.go b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/utils.go
index 78b791300..8f3f03500 100644
--- a/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/utils.go
+++ b/vendor/github.com/aliyun/aliyun-oss-go-sdk/oss/utils.go
@@ -9,31 +9,33 @@ import (
"io"
"net/http"
"os"
- "os/exec"
"runtime"
"strconv"
"strings"
"time"
+ "unicode/utf8"
)
var sys_name string
var sys_release string
var sys_machine string
+var (
+ escQuot = []byte(""") // shorter than """
+ escApos = []byte("'") // shorter than "'"
+ escAmp = []byte("&")
+ escLT = []byte("<")
+ escGT = []byte(">")
+ escTab = []byte(" ")
+ escNL = []byte("
")
+ escCR = []byte("
")
+ escFFFD = []byte("\uFFFD") // Unicode replacement character
+)
+
func init() {
sys_name = runtime.GOOS
sys_release = "-"
sys_machine = runtime.GOARCH
-
- if out, err := exec.Command("uname", "-s").CombinedOutput(); err == nil {
- sys_name = string(bytes.TrimSpace(out))
- }
- if out, err := exec.Command("uname", "-r").CombinedOutput(); err == nil {
- sys_release = string(bytes.TrimSpace(out))
- }
- if out, err := exec.Command("uname", "-m").CombinedOutput(); err == nil {
- sys_machine = string(bytes.TrimSpace(out))
- }
}
// userAgent gets user agent
@@ -376,6 +378,11 @@ func ChoiceCompletePartOption(options []Option) []Option {
}
}
+ notification, _ := FindOption(options, HttpHeaderOssNotification, nil)
+ if notification != nil {
+ outOption = append(outOption, SetHeader(HttpHeaderOssNotification, notification))
+ }
+
return outOption
}
@@ -435,28 +442,90 @@ func CheckBucketName(bucketName string) error {
return nil
}
+func CheckObjectName(objectName string) error {
+ if len(objectName) == 0 {
+ return fmt.Errorf("object name is empty")
+ }
+ return nil
+}
+
+func CheckObjectNameEx(objectName string, strict bool) error {
+ if err := CheckObjectName(objectName); err != nil {
+ return err
+ }
+
+ if strict && strings.HasPrefix(objectName, "?") {
+ return fmt.Errorf("object name is invalid, can't start with '?'")
+ }
+
+ return nil
+}
+
+/*
+ func GetReaderLen(reader io.Reader) (int64, error) {
+ var contentLength int64
+ var err error
+ switch v := reader.(type) {
+ case *bytes.Buffer:
+ contentLength = int64(v.Len())
+ case *bytes.Reader:
+ contentLength = int64(v.Len())
+ case *strings.Reader:
+ contentLength = int64(v.Len())
+ case *os.File:
+ fInfo, fError := v.Stat()
+ if fError != nil {
+ err = fmt.Errorf("can't get reader content length,%s", fError.Error())
+ } else {
+ contentLength = fInfo.Size()
+ }
+ case *io.LimitedReader:
+ contentLength = int64(v.N)
+ case *LimitedReadCloser:
+ contentLength = int64(v.N)
+ default:
+ err = fmt.Errorf("can't get reader content length,unkown reader type")
+ }
+ return contentLength, err
+ }
+*/
+
func GetReaderLen(reader io.Reader) (int64, error) {
var contentLength int64
var err error
switch v := reader.(type) {
- case *bytes.Buffer:
- contentLength = int64(v.Len())
- case *bytes.Reader:
- contentLength = int64(v.Len())
- case *strings.Reader:
- contentLength = int64(v.Len())
- case *os.File:
- fInfo, fError := v.Stat()
- if fError != nil {
- err = fmt.Errorf("can't get reader content length,%s", fError.Error())
- } else {
- contentLength = fInfo.Size()
- }
case *io.LimitedReader:
contentLength = int64(v.N)
case *LimitedReadCloser:
contentLength = int64(v.N)
default:
+ // Len
+ type lenner interface {
+ Len() int
+ }
+ if lr, ok := reader.(lenner); ok {
+ return int64(lr.Len()), nil
+ }
+ // seeker len
+ if s, ok := reader.(io.Seeker); ok {
+ curOffset, err := s.Seek(0, io.SeekCurrent)
+ if err != nil {
+ return 0, err
+ }
+ endOffset, err := s.Seek(0, io.SeekEnd)
+ if err != nil {
+ return 0, err
+ }
+ _, err = s.Seek(curOffset, io.SeekStart)
+ if err != nil {
+ return 0, err
+ }
+ n := endOffset - curOffset
+ if n >= 0 {
+ return n, nil
+ }
+ }
+ //
err = fmt.Errorf("can't get reader content length,unkown reader type")
}
return contentLength, err
@@ -520,3 +589,86 @@ func ConvertEmptyValueToNil(params map[string]interface{}, keys []string) {
}
}
}
+
+func EscapeLFString(str string) string {
+ var log bytes.Buffer
+ for i := 0; i < len(str); i++ {
+ if str[i] != '\n' {
+ log.WriteByte(str[i])
+ } else {
+ log.WriteString("\\n")
+ }
+ }
+ return log.String()
+}
+
+// EscapeString writes to p the properly escaped XML equivalent
+// of the plain text data s.
+func EscapeXml(s string) string {
+ var p strings.Builder
+ var esc []byte
+ hextable := "0123456789ABCDEF"
+ escPattern := []byte("")
+ last := 0
+ for i := 0; i < len(s); {
+ r, width := utf8.DecodeRuneInString(s[i:])
+ i += width
+ switch r {
+ case '"':
+ esc = escQuot
+ case '\'':
+ esc = escApos
+ case '&':
+ esc = escAmp
+ case '<':
+ esc = escLT
+ case '>':
+ esc = escGT
+ case '\t':
+ esc = escTab
+ case '\n':
+ esc = escNL
+ case '\r':
+ esc = escCR
+ default:
+ if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
+ if r >= 0x00 && r < 0x20 {
+ escPattern[3] = hextable[r>>4]
+ escPattern[4] = hextable[r&0x0f]
+ esc = escPattern
+ } else {
+ esc = escFFFD
+ }
+ break
+ }
+ continue
+ }
+ p.WriteString(s[last : i-width])
+ p.Write(esc)
+ last = i
+ }
+ p.WriteString(s[last:])
+ return p.String()
+}
+
+// Decide whether the given rune is in the XML Character Range, per
+// the Char production of https://www.xml.com/axml/testaxml.htm,
+// Section 2.2 Characters.
+func isInCharacterRange(r rune) (inrange bool) {
+ return r == 0x09 ||
+ r == 0x0A ||
+ r == 0x0D ||
+ r >= 0x20 && r <= 0xD7FF ||
+ r >= 0xE000 && r <= 0xFFFD ||
+ r >= 0x10000 && r <= 0x10FFFF
+}
+
+func isVerifyObjectStrict(config *Config) bool {
+ if config != nil {
+ if config.AuthVersion == AuthV2 || config.AuthVersion == AuthV4 {
+ return false
+ }
+ return config.VerifyObjectStrict
+ }
+ return true
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 25ac1c984..4bb964261 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -70,7 +70,7 @@ github.com/Masterminds/semver
# github.com/Masterminds/sprig v2.22.0+incompatible
## explicit
github.com/Masterminds/sprig
-# github.com/aliyun/aliyun-oss-go-sdk v2.1.8+incompatible
+# github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible
## explicit
github.com/aliyun/aliyun-oss-go-sdk/oss
# github.com/aws/aws-sdk-go v1.54.20
@@ -127,8 +127,6 @@ github.com/aws/aws-sdk-go/service/sso/ssoiface
github.com/aws/aws-sdk-go/service/ssooidc
github.com/aws/aws-sdk-go/service/sts
github.com/aws/aws-sdk-go/service/sts/stsiface
-# github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f
-## explicit
# github.com/beorn7/perks v1.0.1
## explicit; go 1.11
github.com/beorn7/perks/quantile
@@ -429,8 +427,6 @@ github.com/prometheus/procfs/internal/util
# github.com/robfig/cron/v3 v3.0.1
## explicit; go 1.12
github.com/robfig/cron/v3
-# github.com/satori/go.uuid v1.2.0
-## explicit
# github.com/sirupsen/logrus v1.9.3
## explicit; go 1.13
github.com/sirupsen/logrus