|
@@ -1146,43 +1146,42 @@ func GetSHA256Digest(r io.Reader) (string, int64) {
|
|
var errUnauthorized = fmt.Errorf("unauthorized")
|
|
var errUnauthorized = fmt.Errorf("unauthorized")
|
|
|
|
|
|
func makeRequestWithRetry(ctx context.Context, method string, requestURL *url.URL, headers http.Header, body io.ReadSeeker, regOpts *RegistryOptions) (*http.Response, error) {
|
|
func makeRequestWithRetry(ctx context.Context, method string, requestURL *url.URL, headers http.Header, body io.ReadSeeker, regOpts *RegistryOptions) (*http.Response, error) {
|
|
- lastErr := errMaxRetriesExceeded
|
|
|
|
- for try := 0; try < maxRetries; try++ {
|
|
|
|
- resp, err := makeRequest(ctx, method, requestURL, headers, body, regOpts)
|
|
|
|
|
|
+ resp, err := makeRequest(ctx, method, requestURL, headers, body, regOpts)
|
|
|
|
+ if err != nil {
|
|
|
|
+ if !errors.Is(err, context.Canceled) {
|
|
|
|
+ log.Printf("request failed: %v", err)
|
|
|
|
+ }
|
|
|
|
+ return nil, err
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ switch {
|
|
|
|
+ case resp.StatusCode == http.StatusUnauthorized:
|
|
|
|
+ // Handle authentication error with one retry
|
|
|
|
+ auth := resp.Header.Get("www-authenticate")
|
|
|
|
+ authRedir := ParseAuthRedirectString(auth)
|
|
|
|
+ token, err := getAuthToken(ctx, authRedir)
|
|
if err != nil {
|
|
if err != nil {
|
|
- log.Printf("couldn't start upload: %v", err)
|
|
|
|
return nil, err
|
|
return nil, err
|
|
}
|
|
}
|
|
-
|
|
|
|
- switch {
|
|
|
|
- case resp.StatusCode == http.StatusUnauthorized:
|
|
|
|
- auth := resp.Header.Get("www-authenticate")
|
|
|
|
- authRedir := ParseAuthRedirectString(auth)
|
|
|
|
- token, err := getAuthToken(ctx, authRedir)
|
|
|
|
|
|
+ regOpts.Token = token
|
|
|
|
+ if body != nil {
|
|
|
|
+ _, err = body.Seek(0, io.SeekStart)
|
|
if err != nil {
|
|
if err != nil {
|
|
return nil, err
|
|
return nil, err
|
|
}
|
|
}
|
|
-
|
|
|
|
- regOpts.Token = token
|
|
|
|
- if body != nil {
|
|
|
|
- body.Seek(0, io.SeekStart)
|
|
|
|
- }
|
|
|
|
- lastErr = errUnauthorized
|
|
|
|
- case resp.StatusCode == http.StatusNotFound:
|
|
|
|
- return nil, os.ErrNotExist
|
|
|
|
- case resp.StatusCode >= http.StatusBadRequest:
|
|
|
|
- body, err := io.ReadAll(resp.Body)
|
|
|
|
- if err != nil {
|
|
|
|
- return nil, fmt.Errorf("%d: %s", resp.StatusCode, err)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return nil, fmt.Errorf("%d: %s", resp.StatusCode, body)
|
|
|
|
- default:
|
|
|
|
- return resp, nil
|
|
|
|
}
|
|
}
|
|
|
|
+ return makeRequest(ctx, method, requestURL, headers, body, regOpts)
|
|
|
|
+ case resp.StatusCode == http.StatusNotFound:
|
|
|
|
+ return nil, os.ErrNotExist
|
|
|
|
+ case resp.StatusCode >= http.StatusBadRequest:
|
|
|
|
+ responseBody, err := io.ReadAll(resp.Body)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return nil, fmt.Errorf("%d: %s", resp.StatusCode, err)
|
|
|
|
+ }
|
|
|
|
+ return nil, fmt.Errorf("%d: %s", resp.StatusCode, responseBody)
|
|
}
|
|
}
|
|
|
|
|
|
- return nil, lastErr
|
|
|
|
|
|
+ return resp, nil
|
|
}
|
|
}
|
|
|
|
|
|
func makeRequest(ctx context.Context, method string, requestURL *url.URL, headers http.Header, body io.Reader, regOpts *RegistryOptions) (*http.Response, error) {
|
|
func makeRequest(ctx context.Context, method string, requestURL *url.URL, headers http.Header, body io.Reader, regOpts *RegistryOptions) (*http.Response, error) {
|