@@ -240,14 +240,14 @@ func Download(ctx context.Context, local, remote string, opts ...Opt) (*Result,
240
240
return nil , err
241
241
}
242
242
} else {
243
- if match , err := matchLastModified (ctx , shadTime , remote ); err != nil {
243
+ if match , lmCached , lmRemote , err := matchLastModified (ctx , shadTime , remote ); err != nil {
244
244
logrus .WithError (err ).Info ("Failed to retrieve last-modified for cached digest-less image; using cached image." )
245
245
} else if match {
246
246
if err := copyLocal (ctx , localPath , shadData , ext , o .decompress , o .description , o .expectedDigest ); err != nil {
247
247
return nil , err
248
248
}
249
249
} else {
250
- logrus .Info ("Re-downloading digest-less image: last-modified mismatch detected." )
250
+ logrus .Infof ("Re-downloading digest-less image: last-modified mismatch (cached: %q, remote: %q)" , lmCached , lmRemote )
251
251
useCache = false
252
252
}
253
253
}
@@ -526,25 +526,41 @@ func validateLocalFileDigest(localPath string, expectedDigest digest.Digest) err
526
526
return nil
527
527
}
528
528
529
- func matchLastModified (ctx context.Context , lastModified , url string ) (bool , error ) {
530
- if lastModified == "" {
531
- return false , nil
529
+ // mathLastModified takes params:
530
+ // - ctx: context for calling httpclientutil.Head
531
+ // - lastModifiedPath: path of the cached last-modified time file
532
+ // - url: URL to fetch the last-modified time
533
+ //
534
+ // returns:
535
+ // - matched: whether the last-modified time matches
536
+ // - lmCached: last-modified time string from the lastModifiedPath
537
+ // - lmRemote: last-modified time string from the URL
538
+ // - err: error if fetching the last-modified time from the URL fails
539
+ func matchLastModified (ctx context.Context , lastModifiedPath , url string ) (matched bool , lmCached , lmRemote string , err error ) {
540
+ lmCached = readFile (lastModifiedPath )
541
+ if lmCached == "" {
542
+ return false , "<not cached>" , "<not checked>" , nil
532
543
}
533
544
resp , err := httpclientutil .Head (ctx , http .DefaultClient , url )
534
545
if err != nil {
535
- return false , err
546
+ return false , lmCached , "<failed to fetch remote>" , err
536
547
}
537
548
defer resp .Body .Close ()
538
- lm := resp .Header .Get ("Last-Modified" )
539
- if lm == "" {
540
- return false , nil
541
- }
542
- lmTime , err := time .Parse (http .TimeFormat , lm )
543
- if err != nil {
544
- return false , nil
545
- }
546
- lastModifiedTime := readTime (lastModified )
547
- return lmTime .Equal (lastModifiedTime ), nil
549
+ lmRemote = resp .Header .Get ("Last-Modified" )
550
+ if lmRemote == "" {
551
+ return false , lmCached , "<missing header>" , nil
552
+ }
553
+ lmCachedTime , errParsingCachedTime := time .Parse (http .TimeFormat , lmCached )
554
+ lmRemoteTime , errParsingRemoteTime := time .Parse (http .TimeFormat , lmRemote )
555
+ if errParsingCachedTime != nil && errParsingRemoteTime != nil {
556
+ // both time strings are failed to parse, so compare them as strings
557
+ return lmCached == lmRemote , lmCached , lmRemote , nil
558
+ } else if errParsingCachedTime == nil && errParsingRemoteTime == nil {
559
+ // both time strings are successfully parsed, so compare them as times
560
+ return lmRemoteTime .Equal (lmCachedTime ), lmCached , lmRemote , nil
561
+ }
562
+ // ignore parsing errors for either time string and assume they are different
563
+ return false , lmCached , lmRemote , nil
548
564
}
549
565
550
566
func downloadHTTP (ctx context.Context , localPath , lastModified , contentType , url , description string , expectedDigest digest.Digest ) error {
0 commit comments