Set X-Cache and X-Cache-Lookup headers for cache (#8794)

X-Cache sets cache status of HIT if object is
served from the disk cache, or MISS otherwise.
X-Cache-Lookup is set to HIT if object was found
in the cache even if not served (for e.g. if cache
 entry was invalidated by ETag verification)
This commit is contained in:
poornas 2020-01-10 20:21:13 -08:00 committed by kannappanr
parent 2bf6cf0e15
commit 9199033db7
6 changed files with 50 additions and 10 deletions

View file

@ -91,7 +91,10 @@ func setObjectHeaders(w http.ResponseWriter, objInfo ObjectInfo, rs *HTTPRangeSp
if !objInfo.Expires.IsZero() {
w.Header().Set(xhttp.Expires, objInfo.Expires.UTC().Format(http.TimeFormat))
}
if globalCacheConfig.Enabled {
w.Header().Set(xhttp.XCache, objInfo.CacheStatus.String())
w.Header().Set(xhttp.XCacheLookup, objInfo.CacheLookupStatus.String())
}
// Set all other user defined metadata.
for k, v := range objInfo.UserDefined {
if HasPrefix(k, ReservedMetadataPrefix) {

View file

@ -89,8 +89,10 @@ func (m *cacheMeta) ToObjectInfo(bucket, object string) (o ObjectInfo) {
}
o = ObjectInfo{
Bucket: bucket,
Name: object,
Bucket: bucket,
Name: object,
CacheStatus: CacheHit,
CacheLookupStatus: CacheHit,
}
// We set file info only if its valid.

View file

@ -28,6 +28,24 @@ import (
"github.com/minio/minio/cmd/crypto"
)
// CacheStatusType - whether the request was served from cache.
type CacheStatusType string
const (
// CacheHit - whether object was served from cache.
CacheHit CacheStatusType = "HIT"
// CacheMiss - object served from backend.
CacheMiss CacheStatusType = "MISS"
)
func (c CacheStatusType) String() string {
if c != "" {
return string(c)
}
return string(CacheMiss)
}
type cacheControl struct {
expiry time.Time
maxAge int

View file

@ -223,7 +223,10 @@ func (c *cacheObjects) GetObjectNInfo(ctx context.Context, bucket, object string
}
if cc.noStore {
c.cacheStats.incMiss()
return c.GetObjectNInfo(ctx, bucket, object, rs, h, lockType, opts)
bReader, err := c.GetObjectNInfo(ctx, bucket, object, rs, h, lockType, opts)
bReader.ObjInfo.CacheLookupStatus = CacheHit
bReader.ObjInfo.CacheStatus = CacheMiss
return bReader, err
}
}
@ -272,8 +275,14 @@ func (c *cacheObjects) GetObjectNInfo(ctx context.Context, bucket, object string
default:
}
}
bkReader, bkErr := c.GetObjectNInfoFn(ctx, bucket, object, rs, h, lockType, opts)
// Record if cache has a hit that was invalidated by ETag verification
if cacheErr == nil {
bkReader.ObjInfo.CacheLookupStatus = CacheHit
}
if !dcache.diskAvailable(objInfo.Size) {
return c.GetObjectNInfoFn(ctx, bucket, object, rs, h, lockType, opts)
return bkReader, bkErr
}
if rs != nil {
@ -290,12 +299,9 @@ func (c *cacheObjects) GetObjectNInfo(ctx context.Context, bucket, object string
c.put(ctx, dcache, bucket, object, bReader, bReader.ObjInfo.Size, rs, ObjectOptions{UserDefined: getMetadata(bReader.ObjInfo)})
}
}()
return c.GetObjectNInfoFn(ctx, bucket, object, rs, h, lockType, opts)
}
bkReader, bkErr := c.GetObjectNInfoFn(ctx, bucket, object, rs, h, lockType, opts)
if bkErr != nil {
return nil, bkErr
return bkReader, bkErr
}
// Initialize pipe.
pipeReader, pipeWriter := io.Pipe()
teeReader := io.TeeReader(bkReader, pipeWriter)

View file

@ -40,6 +40,12 @@ const (
Action = "Action"
)
// Non standard S3 HTTP response constants
const (
XCache = "X-Cache"
XCacheLookup = "X-Cache-Lookup"
)
// Standard S3 HTTP request constants
const (
IfModifiedSince = "If-Modified-Since"

View file

@ -143,6 +143,11 @@ type ObjectInfo struct {
// Date and time at which the object is no longer able to be cached
Expires time.Time
// CacheStatus sets status of whether this is a cache hit/miss
CacheStatus CacheStatusType
// CacheLookupStatus sets whether a cacheable response is present in the cache
CacheLookupStatus CacheStatusType
// Specify object storage class
StorageClass string