Signed-off-by: Maartje Eyskens <maartje@eyskens.me> Co-authored-by: Richard Wall <wallrj@users.noreply.github.com>
62 lines
1.8 KiB
Go
62 lines
1.8 KiB
Go
/*
|
|
Copyright 2020 The Jetstack cert-manager contributors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package util
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"math/big"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
// RetryBackoff is the ACME client RetryBackoff that does not retry
|
|
// all retries will be handled by cert-manager
|
|
func RetryBackoff(n int, r *http.Request, resp *http.Response) time.Duration {
|
|
|
|
// According to the spec badNonce is urn:ietf:params:acme:error:badNonce.
|
|
// However, we can not use the request body in here as it is closed already.
|
|
// So we're using its status code instead: 400
|
|
if resp.StatusCode == http.StatusBadRequest {
|
|
// don't retry more than 6 times, if we get 6 nonce mismatches something is quite wrong
|
|
if n > 5 {
|
|
return -1
|
|
}
|
|
if n < 1 {
|
|
// n is used for the backoff time below
|
|
n = 1
|
|
}
|
|
|
|
var jitter time.Duration
|
|
if x, err := rand.Int(rand.Reader, big.NewInt(1000)); err == nil {
|
|
// Set the minimum to 1ms to avoid a case where
|
|
// an invalid Retry-After value is parsed into 0 below,
|
|
// resulting in the 0 returned value which would unintentionally
|
|
// stop the retries.
|
|
jitter = (1 + time.Duration(x.Int64())) * time.Millisecond
|
|
}
|
|
|
|
d := time.Duration(1<<uint(n-1))*time.Second + jitter
|
|
if d > 3*time.Second {
|
|
return 3 * time.Second
|
|
}
|
|
return d
|
|
}
|
|
|
|
// do not retry any non badNonce errors
|
|
return -1
|
|
}
|