in getdeps/fetch.go [22:84]
func fetch(label, urlStr string) ([]byte, error) {
log.Printf("%s: Downloading %s...", label, urlStr)
// Get the data
var (
resp *http.Response
err error
)
client := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
// some servers will behave differently upon redirects if a Referer
// header is found, and this may cause the download to fail. So here
// we remove the Referer header.
req.Header.Del("Referer")
return nil
},
}
req, err := http.NewRequest("GET", urlStr, nil)
if err != nil {
return nil, fmt.Errorf("Failed to create new http.Request: %w", err)
}
for attempts := 0; attempts < 3; attempts++ {
resp, err = client.Do(req)
if err != nil {
if uErr, ok := err.(*url.Error); ok {
if uErr.Temporary() || uErr.Timeout() {
// retryable error
log.Printf("Failed to get file, trying again. Error was: %v", err)
continue
}
}
// non-retryable error
return nil, fmt.Errorf("%s: error while downloading %s: %w", label, urlStr, err)
}
defer resp.Body.Close()
log.Printf("Status code is %s", resp.Status)
break
}
// At this point either the last attempt succeeded, or it failed with
// a retryable error, but we are out of retrie.
if err != nil {
return nil, fmt.Errorf("every download attempt has failed. Last error: %v", err)
}
var data []byte
for attempts := 0; attempts < 3; attempts++ {
data, err = ioutil.ReadAll(resp.Body)
if err != nil {
switch err {
case io.ErrUnexpectedEOF, io.ErrClosedPipe:
// retryable error
log.Printf("Failed to retrieve file, trying again. Error was: %v", err)
continue
default:
// non-retryable error
return nil, fmt.Errorf("%s: error while downloading %s: %w", label, urlStr, err)
}
} else {
break
}
}
return data, nil
}