private void CheckRetrieveBeforeSubmit() {
GlobalLog.Assert(_ProtocolStatus == CacheValidationStatus.Continue, "CheckRetrieveBeforeSubmit()|Unexpected _ProtocolStatus = {0}", _ProtocolStatus);
try {
while (true)
{
RequestCacheEntry cacheEntry;
if (_Validator.CacheStream != null && _Validator.CacheStream != Stream.Null)
{
// Reset to Initial state
_Validator.CacheStream.Close();
_Validator.CacheStream = Stream.Null;
}
if (_Validator.StrictCacheErrors)
{
_Validator.CacheStream = _RequestCache.Retrieve(_Validator.CacheKey, out cacheEntry);
}
else
{
Stream stream;
_RequestCache.TryRetrieve(_Validator.CacheKey, out cacheEntry, out stream);
_Validator.CacheStream = stream;
}
if (cacheEntry == null)
{
cacheEntry = new RequestCacheEntry();
cacheEntry.IsPrivateEntry = _RequestCache.IsPrivateCache;
_Validator.FetchCacheEntry(cacheEntry);
}
if (_Validator.CacheStream == null)
{
// If entry does not have a stream an empty stream wrapper must be returned.
// A null or Stream.Null value stands for non existent cache entry.
_Validator.CacheStream = Stream.Null;
}
ValidateFreshness(cacheEntry);
_ProtocolStatus = ValidateCache();
// This will tell us what to do next
switch (_ProtocolStatus) {
case CacheValidationStatus.ReturnCachedResponse:
if (_Validator.CacheStream == null || _Validator.CacheStream == Stream.Null)
{
if(Logging.On) Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_no_cache_entry, "ValidateCache()"));
_ProtocolStatus = CacheValidationStatus.Fail;
_ProtocolException = new InvalidOperationException(SR.GetString(SR.net_cache_no_stream, _Validator.CacheKey));
break;
}
// Final decision is made, check on a range response from cache
Stream stream = _Validator.CacheStream;
// The entry can now be replaced as we are not going for cache entry metadata-only update
_RequestCache.UnlockEntry(_Validator.CacheStream);
if (_Validator.CacheStreamOffset != 0L || _Validator.CacheStreamLength != _Validator.CacheEntry.StreamSize)
{
stream = new RangeStream(stream, _Validator.CacheStreamOffset, _Validator.CacheStreamLength);
if(Logging.On) Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_returned_range_cache, "ValidateCache()", _Validator.CacheStreamOffset, _Validator.CacheStreamLength));
}
_ResponseStream = stream;
_ResponseStreamLength = _Validator.CacheStreamLength;
break;
case CacheValidationStatus.Continue:
// copy a cache stream ref
_ResponseStream = _Validator.CacheStream;
break;
case CacheValidationStatus.RetryResponseFromCache:
// loop thought cache retrieve
continue;
case CacheValidationStatus.DoNotTakeFromCache:
case CacheValidationStatus.DoNotUseCache:
break;
case CacheValidationStatus.Fail:
_ProtocolException = new InvalidOperationException(SR.GetString(SR.net_cache_validator_fail, "ValidateCache"));
break;
default:
_ProtocolStatus = CacheValidationStatus.Fail;
_ProtocolException = new InvalidOperationException(SR.GetString(SR.net_cache_validator_result, "ValidateCache", _Validator.ValidationStatus.ToString()));
if(Logging.On) Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_unexpected_status, "ValidateCache()", _Validator.ValidationStatus.ToString()));
break;
}
break;
}
}
catch (Exception e) {
_ProtocolStatus = CacheValidationStatus.Fail;
_ProtocolException = e;
if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
throw;
}
if(Logging.On) Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_object_and_exception, "CacheProtocol#" + this.GetHashCode().ToString(NumberFormatInfo.InvariantInfo), (e is WebException? e.Message: e.ToString())));
}
finally {
// This is to release cache entry on error
if (_ResponseStream == null && _Validator.CacheStream != null && _Validator.CacheStream != Stream.Null)
{
_Validator.CacheStream.Close();
_Validator.CacheStream = Stream.Null;
}
}
}
//