MCPcopy Create free account
hub / github.com/containers/image / getExternalBlob

Method getExternalBlob

docker/docker_client.go:980–1016  ·  view source on GitHub ↗

getExternalBlob returns the reader of the first available blob URL from urls, which must not be empty. 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).

(ctx context.Context, urls []string)

Source from the content-addressed store, hash-verified

978// This function can return nil reader when no url is supported by this function. In this case, the caller
979// should fallback to fetch the non-external blob (i.e. pull from the registry).
980func (c *dockerClient) getExternalBlob(ctx context.Context, urls []string) (io.ReadCloser, int64, error) {
981 if len(urls) == 0 {
982 return nil, 0, errors.New("internal error: getExternalBlob called with no URLs")
983 }
984 var remoteErrors []error
985 for _, u := range urls {
986 blobURL, err := url.Parse(u)
987 if err != nil || (blobURL.Scheme != "http" && blobURL.Scheme != "https") {
988 continue // unsupported url. skip this url.
989 }
990 // NOTE: we must not authenticate on additional URLs as those
991 // can be abused to leak credentials or tokens. Please
992 // refer to CVE-2020-15157 for more information.
993 resp, err := c.makeRequestToResolvedURL(ctx, http.MethodGet, blobURL, nil, nil, -1, noAuth, nil)
994 if err != nil {
995 remoteErrors = append(remoteErrors, err)
996 continue
997 }
998 if resp.StatusCode != http.StatusOK {
999 err := fmt.Errorf("error fetching external blob from %q: %w", u, newUnexpectedHTTPStatusError(resp))
1000 remoteErrors = append(remoteErrors, err)
1001 logrus.Debug(err)
1002 resp.Body.Close()
1003 continue
1004 }
1005
1006 size, err := getBlobSize(resp)
1007 if err != nil {
1008 size = -1
1009 }
1010 return resp.Body, size, nil
1011 }
1012 if remoteErrors == nil {
1013 return nil, 0, nil // fallback to non-external blob
1014 }
1015 return nil, 0, fmt.Errorf("failed fetching external blob from all urls: %w", multierr.Format("", ", ", "", remoteErrors))
1016}
1017
1018func getBlobSize(resp *http.Response) (int64, error) {
1019 hdrs := resp.Header.Values("Content-Length")

Callers 1

getBlobMethod · 0.95

Calls 6

FormatFunction · 0.92
DebugMethod · 0.80
getBlobSizeFunction · 0.70
CloseMethod · 0.65

Tested by

no test coverage detected