51 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			51 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
	
	
package retryhttp
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"fmt"
 | 
						|
	"io"
 | 
						|
	"net/http"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
func getBody(ctx context.Context, url string) ([]byte, error) {
 | 
						|
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	req.Header.Set("User-Agent", "CRL-Monitor/0.1")
 | 
						|
	resp, err := http.DefaultClient.Do(req)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	defer resp.Body.Close()
 | 
						|
 | 
						|
	body, err := io.ReadAll(resp.Body)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	if resp.StatusCode != http.StatusOK {
 | 
						|
		return nil, fmt.Errorf("http status %d (%s)", resp.StatusCode, string(body))
 | 
						|
	}
 | 
						|
 | 
						|
	return body, nil
 | 
						|
}
 | 
						|
 | 
						|
// Get is a simple wrapper around http.Client.Do that will retry on a fixed backoff schedule
 | 
						|
func Get(ctx context.Context, url string) ([]byte, error) {
 | 
						|
	// A fixed exponential backoff schedule. The final value is zero so that we don't sleep before
 | 
						|
	// returning the final error.
 | 
						|
	var err error
 | 
						|
	for _, backoff := range []int{1000, 1250, 1562, 1953, 2441, 3051, 3814, 4768, 5960, 7450, 9313, 11641, 0} {
 | 
						|
		var body []byte
 | 
						|
		body, err = getBody(ctx, url)
 | 
						|
		if err == nil {
 | 
						|
			return body, nil
 | 
						|
		}
 | 
						|
		time.Sleep(time.Duration(backoff) * time.Millisecond)
 | 
						|
	}
 | 
						|
	return nil, err
 | 
						|
}
 |