Repository: caddyserver/caddy
File: caddyconfig/httploader.go (Go)

Code before:
	}

	return result, nil
}

// Reattempts the http call, waiting `retryDelay` seconds in between attempts.
func doHttpCallWithRetries(ctx caddy.Context, client *http.Client, request *http.Request, retryDelay time.Duration) (*http.Response, error) {
	// make attempt
	resp, err := client.Do(request)
	if err != nil {
		err = fmt.Errorf("problem calling http loader url: %v", err)
	} else if resp.StatusCode < 200 || resp.StatusCode > 499 {
		err = fmt.Errorf("bad response status code from http loader url: %v", resp.StatusCode)
	} else {
		return resp, nil
	}
	// skip retries if valid retryDelay not provided
	if retryDelay <= 0 {
		return resp, err
	}
	// log the error
	caddy.Log().Error(err.Error())
	// wait for the retry delay to lapse before reattempting,
	// or return when context is done
	select {
	case <-time.After(time.Second * retryDelay):
		return doHttpCallWithRetries(ctx, client, request, retryDelay)
	case <-ctx.Done():
		return nil, err
	}
}

func (hl HTTPLoader) makeClient(ctx caddy.Context) (*http.Client, error) {
	client := &http.Client{
		Timeout: time.Duration(hl.Timeout),
	}

	if hl.TLS != nil {
		var tlsConfig *tls.Config

		// client authentication
		if hl.TLS.UseServerIdentity {
			certs, err := ctx.IdentityCredentials(ctx.Logger())
			if err != nil {
				return nil, fmt.Errorf("getting server identity credentials: %v", err)
			}
			if tlsConfig == nil {
				tlsConfig = new(tls.Config)
			}
			tlsConfig.Certificates = certs
		} else if hl.TLS.ClientCertificateFile != "" && hl.TLS.ClientCertificateKeyFile != "" {

Review comment (suggestion):
```suggestion
	case <-time.After(retryDelay):
```

Code after:

func attemptHttpCall(client *http.Client, request *http.Request) (*http.Response, error) {
	resp, err := client.Do(request)
	if err != nil {
		return nil, fmt.Errorf("problem calling http loader url: %v", err)
	} else if resp.StatusCode < 200 || resp.StatusCode > 499 {
		return nil, fmt.Errorf("bad response status code from http loader url: %v", resp.StatusCode)
	}
	return resp, nil
}

func doHttpCallWithRetries(ctx caddy.Context, client *http.Client, request *http.Request) (*http.Response, error) {
	var resp *http.Response
	var err error
	const maxAttempts = 10

	// attempt up to 10 times
	for i := 0; i < maxAttempts; i++ {
		resp, err = attemptHttpCall(client, request)
		if err != nil && i < maxAttempts-1 {
			// wait 500ms before reattempting, or until context is done
			select {
			case <-time.After(time.Millisecond * 500):
			case <-ctx.Done():
				return resp, ctx.Err()
			}
		}
	}

	return resp, err
}

func (hl HTTPLoader) makeClient(ctx caddy.Context) (*http.Client, error) {
	client := &http.Client{
		Timeout: time.Duration(hl.Timeout),
	}

	if hl.TLS != nil {
		var tlsConfig *tls.Config

		// client authentication
		if hl.TLS.UseServerIdentity {
			certs, err := ctx.IdentityCredentials(ctx.Logger())
			if err != nil {
				return nil, fmt.Errorf("getting server identity credentials: %v", err)
			}
			if tlsConfig == nil {
				tlsConfig = new(tls.Config)
			}
			tlsConfig.Certificates = certs
		} else if hl.TLS.ClientCertificateFile != "" && hl.TLS.ClientCertificateKeyFile != "" {