func retryAfter(v string) time.Duration {
	if i, err := strconv.Atoi(v); err == nil {
		return time.Duration(i) * time.Second
	}
	t, err := http.ParseTime(v)
	if err != nil {
		return 0
	}
	return t.Sub(timeNow())
}
retryAfter parses a Retry-After HTTP header value,
trying to convert v into an int (seconds) or use http.ParseTime otherwise.
It returns zero value if v cannot be parsed.
package acme
import (
	"bytes"
	"context"
	"crypto"
	"crypto/rand"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"math/big"
	"net/http"
	"strconv"
	"strings"
	"time"
)
type retryTimer struct {
	backoffFn func(n int, r *http.Request, res *http.Response) time.Duration
	n int
}
func (t *retryTimer) inc() {
	t.n++
}
func (t *retryTimer) backoff(ctx context.Context, r *http.Request, res *http.Response) error {
	d := t.backoffFn(t.n, r, res)
	if d <= 0 {
		return fmt.Errorf("acme: no more retries for %s; tried %d time(s)", r.URL, t.n)
	}
	wakeup := time.NewTimer(d)
	defer wakeup.Stop()
	select {
	case <-ctx.Done():
		return ctx.Err()
	case <-wakeup.C:
		return nil
	}
}
func (c *Client) retryTimer() *retryTimer {
	f := c.RetryBackoff
	if f == nil {
		f = defaultBackoff
	}
	return &retryTimer{backoffFn: f}
}
func defaultBackoff(n int, r *http.Request, res *http.Response) time.Duration {
	const max = 10 * time.Second
	var jitter time.Duration
	if x, err := rand.Int(rand.Reader, big.NewInt(1000)); err == nil {
		jitter = (1 + time.Duration(x.Int64())) * time.Millisecond
	}
	if v, ok := res.Header["Retry-After"]; ok {
		return retryAfter(v[0]) + jitter
	}
	if n < 1 {
		n = 1
	}
	if n > 30 {
		n = 30
	}
	d := time.Duration(1<<uint(n-1))*time.Second + jitter
	if d > max {
		return max
	}
	return d
}