Skip to content

Commit da55d86

Browse files
authored
Do not retry request Do() error in some cases (#1691)
Do not retry the request if: - The client is not able to trust the public certificate received from the server - If the server is HTTP but we sent a HTTPs request
1 parent 797a372 commit da55d86

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

api.go

+4-5
Original file line numberDiff line numberDiff line change
@@ -595,12 +595,11 @@ func (c *Client) executeMethod(ctx context.Context, method string, metadata requ
595595
// Initiate the request.
596596
res, err = c.do(req)
597597
if err != nil {
598-
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
599-
return nil, err
598+
if isRequestErrorRetryable(err) {
599+
// Retry the request
600+
continue
600601
}
601-
602-
// Retry the request
603-
continue
602+
return nil, err
604603
}
605604

606605
// For any known successful http status, return quickly.

retry.go

+23
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ package minio
1919

2020
import (
2121
"context"
22+
"crypto/x509"
23+
"errors"
2224
"net/http"
25+
"net/url"
2326
"time"
2427
)
2528

@@ -123,3 +126,23 @@ func isHTTPStatusRetryable(httpStatusCode int) (ok bool) {
123126
_, ok = retryableHTTPStatusCodes[httpStatusCode]
124127
return ok
125128
}
129+
130+
// For now, all http Do() requests are retriable except some well defined errors
131+
func isRequestErrorRetryable(err error) bool {
132+
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
133+
return false
134+
}
135+
if ue, ok := err.(*url.Error); ok {
136+
e := ue.Unwrap()
137+
switch e.(type) {
138+
// x509: certificate signed by unknown authority
139+
case x509.UnknownAuthorityError:
140+
return false
141+
}
142+
switch e.Error() {
143+
case "http: server gave HTTP response to HTTPS client":
144+
return false
145+
}
146+
}
147+
return true
148+
}

0 commit comments

Comments
 (0)