public static CacheValidationStatus TryResponseFromCache(HttpRequestCacheValidator ctx) {
string ranges;
TriState isRange = CheckForRangeRequest(ctx, out ranges);
if (isRange == TriState.Unknown) {
return CacheValidationStatus.ReturnCachedResponse;
}
if (isRange == TriState.Invalid) {
// user range request
long start = 0;
long end = 0;
long total = 0;
if (!GetBytesRange(ranges, ref start, ref end, ref total, true)) {
if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_range_invalid_format, ranges));
return CacheValidationStatus.DoNotTakeFromCache;
}
if (start >= ctx.CacheEntry.StreamSize
|| end > ctx.CacheEntry.StreamSize
|| (end == -1 && ctx.CacheEntityLength == -1)
|| (end == -1 && ctx.CacheEntityLength > ctx.CacheEntry.StreamSize)
|| (start == -1 && (end == -1
|| ctx.CacheEntityLength == -1
|| (ctx.CacheEntityLength - end >= ctx.CacheEntry.StreamSize))))
{
// we don't have such a range in cache
if(Logging.On)Logging.PrintWarning(Logging.RequestCache, SR.GetString(SR.net_log_cache_range_not_in_cache, ranges));
return CacheValidationStatus.Continue;
}
if (start == -1) {
start = ctx.CacheEntityLength - end;
}
if (end <= 0) {
end = ctx.CacheEntry.StreamSize - 1;
}
ctx.CacheStreamOffset = start;
ctx.CacheStreamLength = end-start+1;
Construct206PartialContent(ctx, (int) start);
if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_range_in_cache, ctx.CacheHeaders[HttpKnownHeaderNames.ContentRange]));
return CacheValidationStatus.ReturnCachedResponse;
}
//
// Here we got a partially cached response and the user wants a whole response
//
if (ctx.Policy.Level == HttpRequestCacheLevel.CacheOnly &&
((object)ctx.Uri.Scheme == (object)Uri.UriSchemeHttp ||
(object)ctx.Uri.Scheme == (object)Uri.UriSchemeHttps))
{
// Here we should strictly report a failure
// Only for HTTP and HTTPS we choose to return a partial content even user did not ask for it
ctx.CacheStreamOffset = 0;
ctx.CacheStreamLength = ctx.CacheEntry.StreamSize;
Construct206PartialContent(ctx, 0);
if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_partial_resp, ctx.CacheHeaders[HttpKnownHeaderNames.ContentRange]));
return CacheValidationStatus.ReturnCachedResponse;
}
if (ctx.CacheEntry.StreamSize >= Int32.MaxValue) {
if(Logging.On)Logging.PrintWarning(Logging.RequestCache, SR.GetString(SR.net_log_cache_entry_size_too_big, ctx.CacheEntry.StreamSize));
return CacheValidationStatus.DoNotTakeFromCache;
}
if (TryConditionalRangeRequest(ctx)) {
ctx.RequestRangeCache = true;
((HttpWebRequest)ctx.Request).AddRange((int)ctx.CacheEntry.StreamSize);
if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_range, ctx.Request.Headers[HttpKnownHeaderNames.Range]));
return CacheValidationStatus.Continue;
}
// This will let an unconditional request go
return CacheValidationStatus.Continue;
}