4242 hostSuffix = regexp .MustCompile (`^.*((cos|cos-internal|cos-website|ci)\.[a-z-1]+|file)\.(myqcloud\.com|tencentcos\.cn).*$` )
4343 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).*$` )
4444 invalidBucketErr = fmt .Errorf ("invalid bucket format, please check your cos.BaseURL" )
45+
46+ switchHost = regexp .MustCompile (`([a-z0-9-]+-[0-9]+\.)((cos|cos-website)\.[a-z-1]+)\.(myqcloud\.com)(:[0-9]+){0,1}$` )
47+ oldDomainSuffix = ".myqcloud.com"
48+ newDomainSuffix = ".tencentcos.cn"
4549)
4650
4751// BaseURL 访问各 API 所需的基础 URL
@@ -89,9 +93,9 @@ func NewBucketURL(bucketName, region string, secure bool) (*url.URL, error) {
8993}
9094
9195type RetryOptions struct {
92- Count int
93- Interval time.Duration
94- StatusCode [] int
96+ Count int
97+ Interval time.Duration
98+ AutoSwitchHost bool
9599}
96100type Config struct {
97101 EnableCRC bool
@@ -148,8 +152,9 @@ func NewClient(uri *BaseURL, httpClient *http.Client) *Client {
148152 EnableCRC : true ,
149153 RequestBodyClose : false ,
150154 RetryOpt : RetryOptions {
151- Count : 3 ,
152- Interval : time .Duration (0 ),
155+ Count : 3 ,
156+ Interval : time .Duration (0 ),
157+ AutoSwitchHost : true ,
153158 },
154159 },
155160 }
@@ -352,6 +357,22 @@ type sendOptions struct {
352357 disableCloseBody bool
353358}
354359
360+ func toSwitchHost (oldURL * url.URL ) * url.URL {
361+ // 判断域名是否能够切换
362+ if ! switchHost .MatchString (oldURL .Host ) {
363+ return oldURL
364+ }
365+ newURL , _ := url .Parse (oldURL .String ())
366+ hostAndPort := strings .SplitN (newURL .Host , ":" , 2 )
367+ newHost := hostAndPort [0 ]
368+ newHost = newHost [:len (newHost )- len (oldDomainSuffix )] + newDomainSuffix
369+ if len (hostAndPort ) > 1 {
370+ newHost += ":" + hostAndPort [1 ]
371+ }
372+ newURL .Host = newHost
373+ return newURL
374+ }
375+
355376func (c * Client ) doRetry (ctx context.Context , opt * sendOptions ) (resp * Response , err error ) {
356377 if opt .body != nil {
357378 if _ , ok := opt .body .(io.Reader ); ok {
@@ -360,36 +381,31 @@ func (c *Client) doRetry(ctx context.Context, opt *sendOptions) (resp *Response,
360381 }
361382 }
362383 count := 1
363- if count < c .Conf .RetryOpt .Count {
384+ if c .Conf .RetryOpt .Count > 0 {
364385 count = c .Conf .RetryOpt .Count
365386 }
366- nr := 0
367387 interval := c .Conf .RetryOpt .Interval
368- for nr < count {
388+ for nr := 0 ; nr < count ; nr ++ {
369389 resp , err = c .send (ctx , opt )
370390 if err != nil && err != invalidBucketErr {
371- if resp != nil && resp .StatusCode <= 499 {
372- dobreak := true
373- for _ , v := range c .Conf .RetryOpt .StatusCode {
374- if resp .StatusCode == v {
375- dobreak = false
376- break
377- }
378- }
379- if dobreak {
380- break
391+ // 不重试
392+ if resp != nil && resp .StatusCode < 500 {
393+ break
394+ }
395+ if c .Conf .RetryOpt .AutoSwitchHost {
396+ // 收不到报文 或者 不存在RequestId
397+ if resp == nil || resp .Header .Get ("X-Cos-Request-Id" ) == "" {
398+ opt .baseURL = toSwitchHost (opt .baseURL )
381399 }
382400 }
383- nr ++
384- if interval > 0 && nr < count {
401+ if interval > 0 && nr + 1 < count {
385402 time .Sleep (interval )
386403 }
387404 continue
388405 }
389406 break
390407 }
391408 return
392-
393409}
394410func (c * Client ) send (ctx context.Context , opt * sendOptions ) (resp * Response , err error ) {
395411 req , err := c .newRequest (ctx , opt .baseURL , opt .uri , opt .method , opt .body , opt .optQuery , opt .optHeader )
0 commit comments