@@ -229,6 +229,7 @@ func Download(ctx context.Context, local, remote string, opts ...Opt) (*Result,
229
229
}
230
230
if _ , err := os .Stat (shadData ); err == nil {
231
231
logrus .Debugf ("file %q is cached as %q" , localPath , shadData )
232
+ useCache := true
232
233
if _ , err := os .Stat (shadDigest ); err == nil {
233
234
logrus .Debugf ("Comparing digest %q with the cached digest file %q, not computing the actual digest of %q" ,
234
235
o .expectedDigest , shadDigest , shadData )
@@ -239,18 +240,27 @@ func Download(ctx context.Context, local, remote string, opts ...Opt) (*Result,
239
240
return nil , err
240
241
}
241
242
} else {
242
- if err := copyLocal (ctx , localPath , shadData , ext , o . decompress , o . description , o . expectedDigest ); err != nil {
243
+ if match , err := matchLastModified (ctx , shadTime , remote ); err != nil {
243
244
return nil , err
245
+ } else if match {
246
+ if err := copyLocal (ctx , localPath , shadData , ext , o .decompress , o .description , o .expectedDigest ); err != nil {
247
+ return nil , err
248
+ }
249
+ } else {
250
+ logrus .Info ("Re-downloading digest-less image: last-modified mismatch detected." )
251
+ useCache = false
244
252
}
245
253
}
246
- res := & Result {
247
- Status : StatusUsedCache ,
248
- CachePath : shadData ,
249
- LastModified : readTime (shadTime ),
250
- ContentType : readFile (shadType ),
251
- ValidatedDigest : o .expectedDigest != "" ,
254
+ if useCache {
255
+ res := & Result {
256
+ Status : StatusUsedCache ,
257
+ CachePath : shadData ,
258
+ LastModified : readTime (shadTime ),
259
+ ContentType : readFile (shadType ),
260
+ ValidatedDigest : o .expectedDigest != "" ,
261
+ }
262
+ return res , nil
252
263
}
253
- return res , nil
254
264
}
255
265
if err := os .RemoveAll (shad ); err != nil {
256
266
return nil , err
@@ -516,6 +526,27 @@ func validateLocalFileDigest(localPath string, expectedDigest digest.Digest) err
516
526
return nil
517
527
}
518
528
529
+ func matchLastModified (ctx context.Context , lastModified , url string ) (bool , error ) {
530
+ if lastModified == "" {
531
+ return false , nil
532
+ }
533
+ resp , err := httpclientutil .Head (ctx , http .DefaultClient , url )
534
+ if err != nil {
535
+ return false , err
536
+ }
537
+ 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
548
+ }
549
+
519
550
func downloadHTTP (ctx context.Context , localPath , lastModified , contentType , url , description string , expectedDigest digest.Digest ) error {
520
551
if localPath == "" {
521
552
return fmt .Errorf ("downloadHTTP: got empty localPath" )
0 commit comments