From 0b19e24d8186b1766ba341269ef8e12ee5181004 Mon Sep 17 00:00:00 2001 From: Bruce MacDonald Date: Fri, 17 Nov 2023 14:22:35 -0500 Subject: [PATCH] only retry once on auth failure (#1175) --- server/images.go | 55 ++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/server/images.go b/server/images.go index 7febb1ef..e5adb64a 100644 --- a/server/images.go +++ b/server/images.go @@ -1146,43 +1146,42 @@ func GetSHA256Digest(r io.Reader) (string, int64) { 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) { - 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 { - log.Printf("couldn't start upload: %v", 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 { 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) {