diff --git a/bucket_lifecycle.go b/bucket_lifecycle.go index 4685a73..f6d5a91 100644 --- a/bucket_lifecycle.go +++ b/bucket_lifecycle.go @@ -70,7 +70,7 @@ func (s *BucketService) GetLifecycle(ctx context.Context) (*BucketGetLifecycleRe method: http.MethodGet, result: &res, } - resp, err := s.client.send(ctx, &sendOpt) + resp, err := s.client.doRetry(ctx, &sendOpt) return &res, resp, err } @@ -90,7 +90,7 @@ func (s *BucketService) PutLifecycle(ctx context.Context, opt *BucketPutLifecycl method: http.MethodPut, body: opt, } - resp, err := s.client.send(ctx, &sendOpt) + resp, err := s.client.doRetry(ctx, &sendOpt) return resp, err } @@ -102,6 +102,6 @@ func (s *BucketService) DeleteLifecycle(ctx context.Context) (*Response, error) uri: "/?lifecycle", method: http.MethodDelete, } - resp, err := s.client.send(ctx, &sendOpt) + resp, err := s.client.doRetry(ctx, &sendOpt) return resp, err } diff --git a/cos.go b/cos.go index 23bcc33..d36666d 100644 --- a/cos.go +++ b/cos.go @@ -22,7 +22,7 @@ import ( const ( // Version current go sdk version - Version = "0.7.27" + Version = "0.7.28" userAgent = "cos-go-sdk-v5/" + Version contentTypeXML = "application/xml" defaultServiceBaseURL = "http://service.cos.myqcloud.com" @@ -213,6 +213,11 @@ func (c *Client) newRequest(ctx context.Context, baseURL *url.URL, uri, method s } func (c *Client) doAPI(ctx context.Context, req *http.Request, result interface{}, closeBody bool) (*Response, error) { + var cancel context.CancelFunc + if closeBody { + ctx, cancel = context.WithCancel(ctx) + defer cancel() + } req = req.WithContext(ctx) resp, err := c.client.Do(req) @@ -290,6 +295,27 @@ type sendOptions struct { disableCloseBody bool } +func (c *Client) doRetry(ctx context.Context, opt *sendOptions) (resp *Response, err error) { + if opt.body != nil { + if _, ok := opt.body.(io.Reader); ok { + return c.send(ctx, opt) + } + } + nr := 0 + for nr < 3 { + resp, err = c.send(ctx, opt) + if err != nil { + if resp != nil && resp.StatusCode <= 499 { + break + } + nr++ + continue + } + break + } + return + +} 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) if err != nil {