protected internal override CacheValidationStatus RevalidateCache()
{
if (this.Policy.Level != HttpRequestCacheLevel.Revalidate && base.Policy.Level >= RequestCacheLevel.Reload)
{
// For those policies cache is never returned
GlobalLog.Assert("RevalidateCache()", "This validator should not be called for policy = " + Policy.ToString());
if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_validator_invalid_for_policy, Policy.ToString()));
return CacheValidationStatus.DoNotTakeFromCache;
}
// First check is do we have a cached entry at all?
// Also we include some very special case where cache got a 304 (NotModified) response somehow
if (CacheStream == Stream.Null || (int)CacheStatusCode == 0 || CacheStatusCode == HttpStatusCode.NotModified)
{
return CacheValidationStatus.DoNotTakeFromCache;
}
//
// This is a second+ time validation after receiving at least one response
//
// Apply our best knowledge of HTTP caching and return the result
// that can be hooked up and revised by the upper level
CacheValidationStatus result = CacheValidationStatus.DoNotTakeFromCache;
HttpWebResponse resp = Response as HttpWebResponse;
if (resp == null)
{
// This will result to an application error
return CacheValidationStatus.DoNotTakeFromCache;
}
if (resp.StatusCode >= HttpStatusCode.InternalServerError) {
// If server returned a 5XX server error
if (Rfc2616.Common.ValidateCacheOn5XXResponse(this) == CacheValidationStatus.ReturnCachedResponse) {
// We can substitute the response from cache
if (CacheFreshnessStatus == CacheFreshnessStatus.Stale) {
CacheHeaders.Add(HttpKnownHeaderNames.Warning, HttpRequestCacheValidator.Warning_110);
}
if (HeuristicExpiration && (int)CacheAge.TotalSeconds >= 24*3600) {
CacheHeaders.Add(HttpKnownHeaderNames.Warning, HttpRequestCacheValidator.Warning_113);
}
// We actually failed to reach the origin server hence we don't reset the current Cache Age
}
}
else {
// if there was already one retry, then cache should not be taken into account
if (ResponseCount > 1) {
result = CacheValidationStatus.DoNotTakeFromCache;
}
else {
/*
Section 13.2.3:
HTTP/1.1 uses the Age response-header to convey the estimated age
of the response message when obtained from a cache.
The Age field value is the cache's estimate of the amount of time
since the response was generated or >>revalidated<< by the origin server.
*/
// Reset Cache Age to be 0 seconds
CacheAge = TimeSpan.Zero;
result = Rfc2616.Common.ValidateCacheAfterResponse(this, resp);
}
}
if (result == CacheValidationStatus.ReturnCachedResponse)
{
CacheHeaders[HttpKnownHeaderNames.Age] = ((int)(CacheAge.TotalSeconds)).ToString(NumberFormatInfo.InvariantInfo);
}
return result;
}