// shouldRetry returns a boolean as to whether this resp and err // deserve to be retried. It returns the err as a convenience func (f *Fs) shouldRetry(resp *http.Response, err error) (bool, error) { if resp != nil { if resp.StatusCode == 401 { f.ts.Invalidate() fs.Log(f, "401 error received - invalidating token") return true, err } // Work around receiving this error sporadically on authentication // // HTTP code 403: "403 Forbidden", reponse body: {"message":"Authorization header requires 'Credential' parameter. Authorization header requires 'Signature' parameter. Authorization header requires 'SignedHeaders' parameter. Authorization header requires existence of either a 'X-Amz-Date' or a 'Date' header. Authorization=Bearer"} if resp.StatusCode == 403 && strings.Contains(err.Error(), "Authorization header requires") { fs.Log(f, "403 \"Authorization header requires...\" error received - retry") return true, err } } return fs.ShouldRetry(err) || fs.ShouldRetryHTTP(resp, retryErrorCodes), err }
// shouldRetryNoAuth returns a boolean as to whether this resp and err // deserve to be retried. It returns the err as a convenience func (f *Fs) shouldRetryNoReauth(resp *http.Response, err error) (bool, error) { // For 429 or 503 errors look at the Retry-After: header and // set the retry appropriately, starting with a minimum of 1 // second if it isn't set. if resp != nil && (resp.StatusCode == 429 || resp.StatusCode == 503) { var retryAfter = 1 retryAfterString := resp.Header.Get(retryAfterHeader) if retryAfterString != "" { var err error retryAfter, err = strconv.Atoi(retryAfterString) if err != nil { fs.ErrorLog(f, "Malformed %s header %q: %v", retryAfterHeader, retryAfterString, err) } } retryAfterDuration := time.Duration(retryAfter) * time.Second if f.pacer.GetSleep() < retryAfterDuration { fs.Debug(f, "Setting sleep to %v after error: %v", retryAfterDuration, err) // We set 1/2 the value here because the pacer will double it immediately f.pacer.SetSleep(retryAfterDuration / 2) } return true, err } return fs.ShouldRetry(err) || fs.ShouldRetryHTTP(resp, retryErrorCodes), err }
// shouldRetry returns a boolean as to whether this resp and err // deserve to be retried. It returns the err as a convenience func shouldRetry(resp *http.Response, err error) (bool, error) { return fs.ShouldRetry(err) || fs.ShouldRetryHTTP(resp, retryErrorCodes), err }