Repository: containerd/containerd
File: core/remotes/docker/resolver.go (Go)

Code before:
		return false, nil
	}
	last := responses[len(responses)-1]
	switch last.StatusCode {
	case http.StatusUnauthorized:
		log.G(ctx).WithField("header", last.Header.Get("WWW-Authenticate")).Debug("Unauthorized")
		if r.host.Authorizer != nil {
			if err := r.host.Authorizer.AddResponses(ctx, responses); err == nil {
				return true, nil
			} else if !errdefs.IsNotImplemented(err) {
				return false, err
			}
		}

		return false, nil
	case http.StatusMethodNotAllowed:
		// Support registries which have not properly implemented the HEAD method for
		// manifests endpoint
		if r.method == http.MethodHead && strings.Contains(r.path, "/manifests/") {
			r.method = http.MethodGet
			return true, nil
		}
	case http.StatusRequestTimeout, http.StatusTooManyRequests:
		return true, nil
	case http.StatusServiceUnavailable, http.StatusGatewayTimeout, http.StatusInternalServerError:
		// Do not retry if there are other servers to try or the same error was seen in the last request
		if !remainingHosts && (len(responses) <= 1 || responses[len(responses)-2].StatusCode != last.StatusCode) {
			return true, nil
		}
	}

	return false, nil
}

func (r *request) String() string {
	return r.host.Scheme + "://" + r.host.Host + r.path
}

func requestFields(req *http.Request) log.Fields {
	fields := map[string]interface{}{
		"request.method": req.Method,
	}
	for k, vals := range req.Header {
		k = strings.ToLower(k)
		if k == "authorization" {
			continue
		}
		for i, v := range vals {
			field := "request.header." + k
			if i > 0 {
				field = fmt.Sprintf("%s.%d", field, i)

Review comment (suggestion):
The comment is slightly confusing at first look because here we are checking if we *should* retry but the comment implies it is checking if it should not retry.

Code after:
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("failed to do request: %w", err)
	}
	log.G(ctx).WithFields(responseFields(resp)).Debug("fetch response received")
	return resp, nil
}

type doChecks func(r *request, resp *http.Response) error

func withErrorCheck(r *request, resp *http.Response) error {
	if resp.StatusCode > 299 {
		if resp.StatusCode == http.StatusNotFound {
			return fmt.Errorf("content at %v not found: %w", r.String(), errdefs.ErrNotFound)
		}
		var registryErr Errors
		if err := json.NewDecoder(resp.Body).Decode(&registryErr); err != nil || registryErr.Len() < 1 {
			return fmt.Errorf("unexpected status code %v: %v", r.String(), resp.Status)
		}
		return fmt.Errorf("unexpected status code %v: %s - Server message: %s", r.String(), resp.Status, registryErr.Error())
	}
	return nil
}

var errContentRangeIgnored = errors.New("content range requests ignored")

func withOffsetCheck(offset int64) doChecks {
	return func(r *request, resp *http.Response) error {
		if offset == 0 {
			return nil
		}
		if resp.StatusCode == http.StatusPartialContent {
			return nil
		}
		if cr := resp.Header.Get("Content-Range"); cr != "" {
			if !strings.HasPrefix(cr, fmt.Sprintf("bytes %d-", offset)) {
				return fmt.Errorf("unhandled content range in response: %v", cr)
			}
			return nil
		}

		// Discard up to offset
		// Could use buffer pool here but this case should be rare
		n, err := io.Copy(io.Discard, io.LimitReader(resp.Body, offset))
		if err != nil {
			return fmt.Errorf("failed to discard to offset: %w", err)
		}
		if n != offset {
			return errors.New("unable to discard to offset")
		}