Skip to content

Commit

Permalink
If we fail fetching a blob from external URLs, report all failures
Browse files Browse the repository at this point in the history
Signed-off-by: Miloslav Trmač <[email protected]>
  • Loading branch information
mtrmac committed Feb 27, 2024
1 parent f62814b commit 01be2f1
Showing 1 changed file with 18 additions and 12 deletions.
30 changes: 18 additions & 12 deletions docker/docker_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -978,34 +978,40 @@ func (c *dockerClient) fetchManifest(ctx context.Context, ref dockerReference, t
// This function can return nil reader when no url is supported by this function. In this case, the caller
// should fallback to fetch the non-external blob (i.e. pull from the registry).
func (c *dockerClient) getExternalBlob(ctx context.Context, urls []string) (io.ReadCloser, int64, error) {
var remoteErrors error
if len(urls) == 0 {
return nil, 0, errors.New("internal error: getExternalBlob called with no URLs")
}
var remoteErrors []error
for _, u := range urls {
blobURL, err := url.Parse(u)
if err != nil || (blobURL.Scheme != "http" && blobURL.Scheme != "https") {
continue // unsupported url. skip this url.
}
var resp *http.Response
// NOTE: we must not authenticate on additional URLs as those
// can be abused to leak credentials or tokens. Please
// refer to CVE-2020-15157 for more information.
resp, remoteErrors = c.makeRequestToResolvedURL(ctx, http.MethodGet, blobURL, nil, nil, -1, noAuth, nil)
if remoteErrors == nil {
if resp.StatusCode != http.StatusOK {
remoteErrors = fmt.Errorf("error fetching external blob from %q: %d (%s)", u, resp.StatusCode, http.StatusText(resp.StatusCode))
logrus.Debug(remoteErrors)
resp.Body.Close()
continue
}
return resp.Body, getBlobSize(resp), nil
resp, err := c.makeRequestToResolvedURL(ctx, http.MethodGet, blobURL, nil, nil, -1, noAuth, nil)
if err != nil {
remoteErrors = append(remoteErrors, err)
continue
}
if resp.StatusCode != http.StatusOK {
err := fmt.Errorf("error fetching external blob from %q: %d (%s)", u, resp.StatusCode, http.StatusText(resp.StatusCode))
remoteErrors = append(remoteErrors, err)
logrus.Debug(err)
resp.Body.Close()
continue
}
return resp.Body, getBlobSize(resp), nil
}
if remoteErrors == nil {
return nil, 0, nil // fallback to non-external blob
}
return nil, 0, remoteErrors
err := fmt.Errorf("failed fetching external blob from all urls: %w", remoteErrors[0])
for _, e := range remoteErrors[1:] {
err = fmt.Errorf("%s, %w", err, e)
}
return nil, 0, err
}

func getBlobSize(resp *http.Response) int64 {
Expand Down

0 comments on commit 01be2f1

Please sign in to comment.