From 70039d904d10c331aefc3b311e09d241cc2c5694 Mon Sep 17 00:00:00 2001 From: jojoliang Date: Mon, 1 Jul 2024 10:50:46 +0800 Subject: [PATCH] =?UTF-8?q?update=20lifecycle,policy,intelligent=20params,?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0=E9=87=8D=E8=AF=95=E6=A0=87=E8=AF=86,?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0upload=E6=97=B6=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E4=BC=A0=E9=80=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bucket_lifecycle.go | 24 +++++++++++++++++------- bucket_policy.go | 1 + cos.go | 28 +++++++++++++++++----------- object.go | 11 ++++++----- 4 files changed, 41 insertions(+), 23 deletions(-) diff --git a/bucket_lifecycle.go b/bucket_lifecycle.go index 9d5e3eb..64f4b06 100644 --- a/bucket_lifecycle.go +++ b/bucket_lifecycle.go @@ -7,8 +7,11 @@ import ( ) type BucketLifecycleAndOperator struct { - Prefix string `xml:"Prefix,omitempty" header:"-"` - Tag []BucketTaggingTag `xml:"Tag,omitempty" header:"-"` + Prefix string `xml:"Prefix,omitempty" header:"-"` + Tag []BucketTaggingTag `xml:"Tag,omitempty" header:"-"` + PrefixNotEquals string `xml:"PrefixNotEquals,omitempty" header:"-"` + ObjectSizeGreaterThan int64 `xml:"ObjectSizeGreaterThan,omitempty" header:"-"` + ObjectSizeLessThan int64 `xml:"ObjectSizeLessThan,omitempty" header:"-"` } // BucketLifecycleFilter is the param of BucketLifecycleRule @@ -25,16 +28,23 @@ type BucketLifecycleExpiration struct { ExpiredObjectDeleteMarker bool `xml:"ExpiredObjectDeleteMarker,omitempty" header:"-"` } +type BucketAccessFrequency struct { + AccessCountLessThan int `xml:"AccessCountLessThan,omitempty" header:"-"` + RecentDays int `xml:"RecentDays,omitempty" header:"-"` +} + // BucketLifecycleTransition is the param of BucketLifecycleRule type BucketLifecycleTransition struct { - Date string `xml:"Date,omitempty" header:"-"` - Days int `xml:"Days,omitempty" header:"-"` - StorageClass string `xml:"StorageClass,omitempty" header:"-"` + Date string `xml:"Date,omitempty" header:"-"` + Days int `xml:"Days,omitempty" header:"-"` + StorageClass string `xml:"StorageClass,omitempty" header:"-"` + AccessFrequency *BucketAccessFrequency `xml:"AccessFrequency,omitempty" header:"-"` } type BucketLifecycleNoncurrentVersion struct { - NoncurrentDays int `xml:"NoncurrentDays,omitempty" header:"-"` - StorageClass string `xml:"StorageClass,omitempty" header:"-"` + NoncurrentDays int `xml:"NoncurrentDays,omitempty" header:"-"` + StorageClass string `xml:"StorageClass,omitempty" header:"-"` + AccessFrequency *BucketAccessFrequency `xml:"AccessFrequency,omitempty" header:"-"` } // BucketLifecycleAbortIncompleteMultipartUpload is the param of BucketLifecycleRule diff --git a/bucket_policy.go b/bucket_policy.go index 5ec4f89..5930198 100644 --- a/bucket_policy.go +++ b/bucket_policy.go @@ -14,6 +14,7 @@ type BucketStatement struct { Effect string `json:"effect,omitempty"` Resource []string `json:"resource,omitempty"` Condition map[string]map[string]interface{} `json:"condition,omitempty"` + Sid string `json:"sid,omitempty"` } type BucketPutPolicyOptions struct { diff --git a/cos.go b/cos.go index cc6c86b..ef626a2 100644 --- a/cos.go +++ b/cos.go @@ -25,7 +25,7 @@ import ( const ( // Version current go sdk version - Version = "0.7.50" + Version = "0.7.52" UserAgent = "cos-go-sdk-v5/" + Version contentTypeXML = "application/xml" defaultServiceBaseURL = "http://service.cos.myqcloud.com" @@ -40,10 +40,10 @@ var ( ) // {|}{bucketname-appid}.{cos|cos-internal|cos-website|ci}.{region}.{myqcloud.com/tencentcos.cn}{/} - hostSuffix = regexp.MustCompile(`^.*((cos|cos-internal|cos-website|ci)\.[a-z-1]+|file)\.(myqcloud\.com|tencentcos\.cn).*$`) - hostPrefix = regexp.MustCompile(`^(http://|https://){0,1}([a-z0-9-]+-[0-9]+\.){0,1}((cos|cos-internal|cos-website|ci)\.[a-z-1]+|file)\.(myqcloud\.com|tencentcos\.cn).*$`) + hostSuffix = regexp.MustCompile(`^.*((cos|cos-internal|cos-website|ci)\.[a-z-1]+|file)\.(myqcloud\.com|tencentcos\.cn).*$`) + hostPrefix = regexp.MustCompile(`^(http://|https://){0,1}([a-z0-9-]+-[0-9]+\.){0,1}((cos|cos-internal|cos-website|ci)\.[a-z-1]+|file)\.(myqcloud\.com|tencentcos\.cn).*$`) metaInsightHostPrefix = regexp.MustCompile(`^(http://|https://){0,1}([0-9]+\.){1}((cos|cos-internal|cos-website|ci)\.[a-z-1]+|file)\.(myqcloud\.com|tencentcos\.cn).*$`) - invalidBucketErr = fmt.Errorf("invalid bucket format, please check your cos.BaseURL") + invalidBucketErr = fmt.Errorf("invalid bucket format, please check your cos.BaseURL") switchHost = regexp.MustCompile(`([a-z0-9-]+-[0-9]+\.)(cos\.[a-z-1]+)\.(myqcloud\.com)(:[0-9]+){0,1}$`) accelerateDomainSuffix = "accelerate.myqcloud.com" @@ -121,11 +121,11 @@ type Client struct { common service - Service *ServiceService - Bucket *BucketService - Object *ObjectService - Batch *BatchService - CI *CIService + Service *ServiceService + Bucket *BucketService + Object *ObjectService + Batch *BatchService + CI *CIService MetaInsight *MetaInsightService Conf *Config @@ -217,7 +217,7 @@ func (c *Client) GetCredential() *Credential { return nil } -func (c *Client) newRequest(ctx context.Context, baseURL *url.URL, uri, method string, body interface{}, optQuery interface{}, optHeader interface{}) (req *http.Request, err error) { +func (c *Client) newRequest(ctx context.Context, baseURL *url.URL, uri, method string, body interface{}, optQuery interface{}, optHeader interface{}, isRetry bool) (req *http.Request, err error) { if !checkURL(baseURL) { host := baseURL.String() if c.BaseURL.MetaInsightURL != baseURL || !metaInsightHostPrefix.MatchString(host) { @@ -273,6 +273,9 @@ func (c *Client) newRequest(ctx context.Context, baseURL *url.URL, uri, method s if req.Header.Get("Content-Type") == "" && contentType != "" { req.Header.Set("Content-Type", contentType) } + if isRetry { + req.Header.Set("X-Cos-Sdk-Retry", "true") + } if c.Host != "" { req.Host = c.Host } @@ -370,6 +373,8 @@ type sendOptions struct { // 是否禁用自动调用 resp.Body.Close() // 自动调用 Close() 是为了能够重用连接 disableCloseBody bool + // 是否重试 + isRetry bool } func toSwitchHost(oldURL *url.URL) *url.URL { @@ -428,6 +433,7 @@ func (c *Client) doRetry(ctx context.Context, opt *sendOptions) (resp *Response, if err != nil { retryErr.Add(err) } + opt.isRetry = nr > 0 resp, err = c.send(ctx, opt) opt.baseURL, retrieable = c.CheckRetrieable(opt.baseURL, resp, err, nr >= count-2) if retrieable { @@ -449,7 +455,7 @@ func (c *Client) doRetry(ctx context.Context, opt *sendOptions) (resp *Response, } func (c *Client) send(ctx context.Context, opt *sendOptions) (resp *Response, err error) { - req, err := c.newRequest(ctx, opt.baseURL, opt.uri, opt.method, opt.body, opt.optQuery, opt.optHeader) + req, err := c.newRequest(ctx, opt.baseURL, opt.uri, opt.method, opt.body, opt.optQuery, opt.optHeader, opt.isRetry) if err != nil { return } diff --git a/object.go b/object.go index 868875a..48b8279 100644 --- a/object.go +++ b/object.go @@ -161,7 +161,7 @@ func (s *ObjectService) GetPresignedURL(ctx context.Context, httpMethod, name, a } } } - req, err := s.client.newRequest(ctx, sendOpt.baseURL, sendOpt.uri, sendOpt.method, sendOpt.body, sendOpt.optQuery, sendOpt.optHeader) + req, err := s.client.newRequest(ctx, sendOpt.baseURL, sendOpt.uri, sendOpt.method, sendOpt.body, sendOpt.optQuery, sendOpt.optHeader, false) if err != nil { return nil, err } @@ -242,7 +242,7 @@ func (s *ObjectService) GetPresignedURL2(ctx context.Context, httpMethod, name s sendOpt.uri = fmt.Sprintf("%s%s%s", sendOpt.uri, mark, url.Values{"x-cos-security-token": []string{cred.SessionToken}}.Encode()) } - req, err := s.client.newRequest(ctx, sendOpt.baseURL, sendOpt.uri, sendOpt.method, sendOpt.body, sendOpt.optQuery, sendOpt.optHeader) + req, err := s.client.newRequest(ctx, sendOpt.baseURL, sendOpt.uri, sendOpt.method, sendOpt.body, sendOpt.optQuery, sendOpt.optHeader, false) if err != nil { return nil, err } @@ -318,7 +318,7 @@ func (s *ObjectService) GetPresignedURL3(ctx context.Context, httpMethod, name s sendOpt.uri = fmt.Sprintf("%s%s%s", sendOpt.uri, mark, url.Values{"x-cos-security-token": []string{cred.SessionToken}}.Encode()) } - req, err := s.client.newRequest(ctx, sendOpt.baseURL, sendOpt.uri, sendOpt.method, sendOpt.body, sendOpt.optQuery, sendOpt.optHeader) + req, err := s.client.newRequest(ctx, sendOpt.baseURL, sendOpt.uri, sendOpt.method, sendOpt.body, sendOpt.optQuery, sendOpt.optHeader, false) if err != nil { return nil, err } @@ -371,7 +371,7 @@ func (s *ObjectService) GetSignature(ctx context.Context, httpMethod, name, ak, sendOpt.uri = fmt.Sprintf("%s?%s", sendOpt.uri, qs) } } - req, err := s.client.newRequest(ctx, sendOpt.baseURL, sendOpt.uri, sendOpt.method, sendOpt.body, sendOpt.optQuery, sendOpt.optHeader) + req, err := s.client.newRequest(ctx, sendOpt.baseURL, sendOpt.uri, sendOpt.method, sendOpt.body, sendOpt.optQuery, sendOpt.optHeader, false) if err != nil { return "" } @@ -771,7 +771,7 @@ type CASJobParameters struct { // ObjectRestoreOptions is the option of object restore type ObjectRestoreOptions struct { XMLName xml.Name `xml:"RestoreRequest" header:"-" url:"-"` - Days int `xml:"Days" header:"-" url:"-"` + Days int `xml:"Days,omitempty" header:"-" url:"-"` Tier *CASJobParameters `xml:"CASJobParameters" header:"-" url:"-"` XOptionHeader *http.Header `xml:"-" header:",omitempty" url:"-"` } @@ -1368,6 +1368,7 @@ func (s *ObjectService) Upload(ctx context.Context, name string, filepath string partOpt.XCosSSECustomerKey = optini.XCosSSECustomerKey partOpt.XCosSSECustomerKeyMD5 = optini.XCosSSECustomerKeyMD5 partOpt.XCosTrafficLimit = optini.XCosTrafficLimit + partOpt.XOptionHeader = optini.XOptionHeader } job := &Jobs{ Name: name,