@@ -408,7 +408,11 @@ func (s *dockerImageSource) GetBlobAt(ctx context.Context, info types.BlobInfo,
408
408
// May update BlobInfoCache, preferably after it knows for certain that a blob truly exists at a specific location.
409
409
func (s * dockerImageSource ) GetBlob (ctx context.Context , info types.BlobInfo , cache types.BlobInfoCache ) (io.ReadCloser , int64 , error ) {
410
410
if len (info .URLs ) != 0 {
411
- return s .getExternalBlob (ctx , info .URLs )
411
+ if r , s , err := s .getExternalBlob (ctx , info .URLs ); err == nil {
412
+ return r , s , nil
413
+ } else if containsValidHTTPURLs (info .URLs ) { // if contains valid HTTP URLs, external blob should be fetched.
414
+ return nil , 0 , err
415
+ } // no understandable urls are contained. Ignore urls and allow fallback.
412
416
}
413
417
414
418
path := fmt .Sprintf (blobsPath , reference .Path (s .physicalRef .ref ), info .Digest .String ())
@@ -425,6 +429,16 @@ func (s *dockerImageSource) GetBlob(ctx context.Context, info types.BlobInfo, ca
425
429
return res .Body , getBlobSize (res ), nil
426
430
}
427
431
432
+ func containsValidHTTPURLs (urls []string ) bool {
433
+ for _ , s := range urls {
434
+ u , err := url .Parse (s )
435
+ if err == nil && (u .Scheme == "http" || u .Scheme == "https" ) {
436
+ return true
437
+ }
438
+ }
439
+ return false
440
+ }
441
+
428
442
// GetSignatures returns the image's signatures. It may use a remote (= slow) service.
429
443
// If instanceDigest is not nil, it contains a digest of the specific manifest instance to retrieve signatures for
430
444
// (when the primary manifest is a manifest list); this never happens if the primary manifest is not a manifest list
0 commit comments