FetchCacheEntry() private method

private FetchCacheEntry ( RequestCacheEntry fetchEntry ) : void
fetchEntry RequestCacheEntry
return void
        //
        // Private methods
        //

        //
        // This method may be invoked as part of the request submission but before issuing a live request
        //
        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;
                }
            }
        }