Add support for missing Cache-Control directives (#8619)

no-cache, only-if-cached and no-store directives are
being enforced in this PR.
master
poornas 5 years ago committed by Nitish Tiwari
parent 476111968a
commit be0c8b1ec0
  1. 39
      cmd/disk-cache-utils.go
  2. 7
      cmd/disk-cache.go

@ -29,11 +29,14 @@ import (
) )
type cacheControl struct { type cacheControl struct {
expiry time.Time expiry time.Time
maxAge int maxAge int
sMaxAge int sMaxAge int
minFresh int minFresh int
maxStale int maxStale int
noStore bool
onlyIfCached bool
noCache bool
} }
func (c cacheControl) isEmpty() bool { func (c cacheControl) isEmpty() bool {
@ -45,6 +48,19 @@ func (c cacheControl) isStale(modTime time.Time) bool {
if c.isEmpty() { if c.isEmpty() {
return false return false
} }
// response will never be stale if only-if-cached is set
if c.onlyIfCached {
return false
}
// Cache-Control value no-store indicates never cache
if c.noStore {
return true
}
// Cache-Control value no-cache indicates cache entry needs to be revalidated before
// serving from cache
if c.noCache {
return true
}
now := time.Now() now := time.Now()
if c.sMaxAge > 0 && c.sMaxAge < int(now.Sub(modTime).Seconds()) { if c.sMaxAge > 0 && c.sMaxAge < int(now.Sub(modTime).Seconds()) {
@ -88,6 +104,19 @@ func cacheControlOpts(o ObjectInfo) (c cacheControl) {
vals := strings.Split(headerVal, ",") vals := strings.Split(headerVal, ",")
for _, val := range vals { for _, val := range vals {
val = strings.TrimSpace(val) val = strings.TrimSpace(val)
if val == "no-store" {
c.noStore = true
continue
}
if val == "only-if-cached" {
c.onlyIfCached = true
continue
}
if val == "no-cache" {
c.noCache = true
continue
}
p := strings.Split(val, "=") p := strings.Split(val, "=")
if len(p) != 2 { if len(p) != 2 {

@ -185,12 +185,17 @@ func (c *cacheObjects) GetObjectNInfo(ctx context.Context, bucket, object string
cacheReader, cacheErr := c.get(ctx, dcache, bucket, object, rs, h, opts) cacheReader, cacheErr := c.get(ctx, dcache, bucket, object, rs, h, opts)
if cacheErr == nil { if cacheErr == nil {
cc = cacheControlOpts(cacheReader.ObjInfo) cc = cacheControlOpts(cacheReader.ObjInfo)
if !cc.isStale(cacheReader.ObjInfo.ModTime) { if (!cc.isEmpty() && !cc.isStale(cacheReader.ObjInfo.ModTime)) ||
cc.onlyIfCached {
// This is a cache hit, mark it so // This is a cache hit, mark it so
c.cacheStats.incHit() c.cacheStats.incHit()
c.cacheStats.incBytesServed(cacheReader.ObjInfo.Size) c.cacheStats.incBytesServed(cacheReader.ObjInfo.Size)
return cacheReader, nil return cacheReader, nil
} }
if cc.noStore {
c.cacheStats.incMiss()
return c.GetObjectNInfo(ctx, bucket, object, rs, h, lockType, opts)
}
} }
// Reaching here implies cache miss // Reaching here implies cache miss

Loading…
Cancel
Save