Exemple #1
0
        // only used by providers
        private static void DependencyRemovedCallback(string key, object value, CacheItemRemovedReason reason)
        {
            Debug.Trace("OutputCache", "DependencyRemovedCallback: reason=" + reason + ", key=" + key);

            DependencyCacheEntry dce = value as DependencyCacheEntry;

            if (dce.KernelCacheEntryKey != null)
            {
                // invalidate kernel cache entry
                if (HttpRuntime.UseIntegratedPipeline)
                {
                    UnsafeIISMethods.MgdFlushKernelCache(dce.KernelCacheEntryKey);
                }
                else
                {
                    UnsafeNativeMethods.InvalidateKernelCache(dce.KernelCacheEntryKey);
                }
            }
            if (reason == CacheItemRemovedReason.DependencyChanged)
            {
                if (dce.OutputCacheEntryKey != null)
                {
                    try {
                        OutputCache.RemoveFromProvider(dce.OutputCacheEntryKey, dce.ProviderName);
                    }
                    catch (Exception e) {
                        HandleErrorWithoutContext(e);
                    }
                }
            }
        }
        OutputCacheProvider FindCacheProvider(HttpApplication app)
        {
            HttpContext ctx = HttpContext.Current;

            if (app == null)
            {
                app = ctx != null ? ctx.ApplicationInstance : null;

                if (app == null)
                {
                    throw new InvalidOperationException("Unable to find output cache provider.");
                }
            }

            string providerName = app.GetOutputCacheProviderName(ctx);

            if (String.IsNullOrEmpty(providerName))
            {
                throw new ProviderException("Invalid OutputCacheProvider name. Name must not be null or an empty string.");
            }

            OutputCacheProvider ret = OutputCache.GetProvider(providerName);

            if (ret == null)
            {
                throw new ProviderException(String.Format("OutputCacheProvider named '{0}' cannot be found.", providerName));
            }

            return(ret);
        }
Exemple #3
0
        // only used by providers
        private static void DependencyRemovedCallbackForFragment(string key, object value, CacheItemRemovedReason reason)
        {
            Debug.Trace("OutputCache", "DependencyRemovedCallbackForFragment: reason=" + reason + ", key=" + key);

            if (reason == CacheItemRemovedReason.DependencyChanged)
            {
                DependencyCacheEntry dce = value as DependencyCacheEntry;
                if (dce.OutputCacheEntryKey != null)
                {
                    try {
                        OutputCache.RemoveFragment(dce.OutputCacheEntryKey, dce.ProviderName);
                    }
                    catch (Exception e) {
                        HandleErrorWithoutContext(e);
                    }
                }
            }
        }
Exemple #4
0
        // lookup fragment
        internal static Object GetFragment(String key, String providerName)
        {
            // if providerName is null, use default provider.
            // if providerName is not null, get it from the provider collection.
            // if it's not in the provider or the default provider is undefined,
            // check the internal cache (we don't know where it is).
            Object result = null;
            OutputCacheProvider provider = GetFragmentProvider(providerName);

            if (provider != null)
            {
                result = provider.Get(key);
                PartialCachingCacheEntry fragment = result as PartialCachingCacheEntry;
                if (fragment != null)
                {
                    if (HasDependencyChanged(true /*isFragment*/, fragment._dependenciesKey, fragment._dependencies, null /*kernelKey*/, key, provider.Name))
                    {
                        OutputCache.RemoveFragment(key, provider.Name);
#if DBG
                        Debug.Trace("OutputCache", "GetFragment(" + key + "," + providerName + ") --> null, " + providerName);
#endif
                        return(null);
                    }
                }
            }

            if (result == null)
            {
                result = HttpRuntime.CacheInternal.Get(key);
#if DBG
                string typeName = (result != null) ? result.GetType().Name : "null";
                Debug.Trace("OutputCache", "GetFragment(" + key + "," + providerName + ") --> " + typeName + ", CacheInternal");
            }
            else
            {
                Debug.Trace("OutputCache", "GetFragment(" + key + "," + providerName + ") --> " + result.GetType().Name + ", " + providerName);
#endif
            }
            return(result);
        }
Exemple #5
0
        // lookup cached vary
        // lookup entry
        // lookup entry for content-encoding
        internal static Object Get(String key)
        {
            // if it's not in the provider or the default provider is undefined,
            // check the internal cache (we don't know where it is).
            Object result = null;
            OutputCacheProvider provider = GetProvider(HttpContext.Current);

            if (provider != null)
            {
                result = provider.Get(key);
                OutputCacheEntry oce = result as OutputCacheEntry;
                if (oce != null)
                {
                    if (HasDependencyChanged(false /*isFragment*/, oce.DependenciesKey, oce.Dependencies, oce.KernelCacheUrl, key, provider.Name))
                    {
                        OutputCache.RemoveFromProvider(key, provider.Name);
#if DBG
                        Debug.Trace("OutputCache", "Get(" + key + ") --> null, " + provider.Name);
#endif
                        return(null);
                    }
                    result = Convert(oce);
                }
            }
            if (result == null)
            {
                result = HttpRuntime.CacheInternal.Get(key);
#if DBG
                string typeName = (result != null) ? result.GetType().Name : "null";
                Debug.Trace("OutputCache", "Get(" + key + ") --> " + typeName + ", CacheInternal");
            }
            else
            {
                Debug.Trace("OutputCache", "Get(" + key + ") --> " + result.GetType().Name + ", " + provider.Name);
#endif
            }
            return(result);
        }
Exemple #6
0
        // insert cached vary or output cache entry
        internal static void InsertResponse(String cachedVaryKey, CachedVary cachedVary,
                                            String rawResponseKey, CachedRawResponse rawResponse,
                                            CacheDependency dependencies,
                                            DateTime absExp, TimeSpan slidingExp)
        {
            // if the provider is undefined or the fragment can't be inserted in the
            // provider, insert it in the internal cache.
            OutputCacheProvider provider = GetProvider(HttpContext.Current);

            //
            // CachedVary can be serialized.
            // CachedRawResponse is not always serializable.
            //

            bool useProvider = (provider != null);

            if (useProvider)
            {
                bool canUseProvider = (IsSubstBlockSerializable(rawResponse._rawResponse) &&
                                       rawResponse._settings.IsValidationCallbackSerializable() &&
                                       slidingExp == Cache.NoSlidingExpiration &&
                                       (dependencies == null || dependencies.IsFileDependency()));

                if (useProvider && !canUseProvider)
                {
                    throw new ProviderException(SR.GetString(SR.Provider_does_not_support_policy_for_responses, provider.Name));
                }
            }

#if DBG
            bool cachedVaryPutInCache = (cachedVary != null);
#endif
            if (cachedVary != null)
            {
                /*
                 * Add the CachedVary item so that a request will know
                 * which headers are needed to issue another request.
                 *
                 * Use the Add method so that we guarantee we only use
                 * a single CachedVary and don't overwrite existing ones.
                 */

                CachedVary cachedVaryInCache;
                if (!useProvider)
                {
                    cachedVaryInCache = OutputCache.UtcAdd(cachedVaryKey, cachedVary);
                }
                else
                {
                    cachedVaryInCache = (CachedVary)provider.Add(cachedVaryKey, cachedVary, Cache.NoAbsoluteExpiration);
                }

                if (cachedVaryInCache != null)
                {
                    if (!cachedVary.Equals(cachedVaryInCache))
                    {
                        if (!useProvider)
                        {
                            HttpRuntime.CacheInternal.UtcInsert(cachedVaryKey, cachedVary);
                        }
                        else
                        {
                            provider.Set(cachedVaryKey, cachedVary, Cache.NoAbsoluteExpiration);
                        }
                    }
                    else
                    {
                        cachedVary = cachedVaryInCache;
#if DBG
                        cachedVaryPutInCache = false;
#endif
                    }
                }

                if (!useProvider)
                {
                    AddCacheKeyToDependencies(ref dependencies, cachedVaryKey);
                }

                // not all caches support cache key dependencies, but we can use a "change number" to associate
                // the ControlCachedVary and the PartialCachingCacheEntry
                rawResponse._cachedVaryId = cachedVary.CachedVaryId;
            }

            // Now insert into the cache (use cache provider if possible, otherwise use internal cache)
            if (!useProvider)
            {
                HttpRuntime.CacheInternal.UtcInsert(rawResponseKey, rawResponse,
                                                    dependencies,
                                                    absExp, slidingExp,
                                                    CacheItemPriority.Normal,
                                                    s_entryRemovedCallback);

                IncrementCount();

                PerfCounters.IncrementCounter(AppPerfCounter.OUTPUT_CACHE_ENTRIES);
                PerfCounters.IncrementCounter(AppPerfCounter.OUTPUT_CACHE_TURNOVER_RATE);
            }
            else
            {
                string   depKey   = null;
                string[] fileDeps = null;
                if (dependencies != null)
                {
                    depKey   = OUTPUTCACHE_KEYPREFIX_DEPENDENCIES + dependencies.GetUniqueID();
                    fileDeps = dependencies.GetFileDependencies();
                }
                OutputCacheEntry oce = Convert(rawResponse, depKey, fileDeps);
                provider.Set(rawResponseKey, oce, absExp);
                if (dependencies != null)
                {
                    // use Add and dispose dependencies if there's already one in the cache
                    Object d = HttpRuntime.CacheInternal.UtcAdd(depKey, new DependencyCacheEntry(rawResponseKey, oce.KernelCacheUrl, provider.Name),
                                                                dependencies,
                                                                absExp, Cache.NoSlidingExpiration,
                                                                CacheItemPriority.Normal, s_dependencyRemovedCallback);
                    if (d != null)
                    {
                        dependencies.Dispose();
                    }
                }
            }
#if DBG
            string cachedVaryType = (cachedVaryPutInCache) ? "CachedVary" : "";
            string providerUsed   = (useProvider) ? provider.Name : "CacheInternal";
            Debug.Trace("OutputCache", "InsertResposne("
                        + cachedVaryKey + ", "
                        + cachedVaryType + ", "
                        + rawResponseKey + ", CachedRawResponse, ...) -->"
                        + providerUsed);
#endif
        }
Exemple #7
0
        // insert fragment
        internal static void InsertFragment(String cachedVaryKey, ControlCachedVary cachedVary,
                                            String fragmentKey, PartialCachingCacheEntry fragment,
                                            CacheDependency dependencies,
                                            DateTime absExp, TimeSpan slidingExp,
                                            String providerName)
        {
            // if providerName is not null, find the provider in the collection.
            // if providerName is null, use default provider.
            // if the default provider is undefined or the fragment can't be inserted in the
            // provider, insert it in the internal cache.
            OutputCacheProvider provider = GetFragmentProvider(providerName);

            //
            // ControlCachedVary and PartialCachingCacheEntry can be serialized
            //

            bool useProvider = (provider != null);

            if (useProvider)
            {
                bool canUseProvider = (slidingExp == Cache.NoSlidingExpiration &&
                                       (dependencies == null || dependencies.IsFileDependency()));

                if (useProvider && !canUseProvider)
                {
                    throw new ProviderException(SR.GetString(SR.Provider_does_not_support_policy_for_fragments, providerName));
                }
            }

#if DBG
            bool cachedVaryPutInCache = (cachedVary != null);
#endif
            if (cachedVary != null)
            {
                // Add the ControlCachedVary item so that a request will know
                // which varies are needed to issue another request.

                // Use the Add method so that we guarantee we only use
                // a single ControlCachedVary and don't overwrite existing ones.
                ControlCachedVary cachedVaryInCache;
                if (!useProvider)
                {
                    cachedVaryInCache = OutputCache.UtcAdd(cachedVaryKey, cachedVary);
                }
                else
                {
                    cachedVaryInCache = (ControlCachedVary)provider.Add(cachedVaryKey, cachedVary, Cache.NoAbsoluteExpiration);
                }

                if (cachedVaryInCache != null)
                {
                    if (!cachedVary.Equals(cachedVaryInCache))
                    {
                        // overwrite existing cached vary
                        if (!useProvider)
                        {
                            HttpRuntime.CacheInternal.UtcInsert(cachedVaryKey, cachedVary);
                        }
                        else
                        {
                            provider.Set(cachedVaryKey, cachedVary, Cache.NoAbsoluteExpiration);
                        }
                    }
                    else
                    {
                        cachedVary = cachedVaryInCache;
#if DBG
                        cachedVaryPutInCache = false;
#endif
                    }
                }

                if (!useProvider)
                {
                    AddCacheKeyToDependencies(ref dependencies, cachedVaryKey);
                }

                // not all caches support cache key dependencies, but we can use a "change number" to associate
                // the ControlCachedVary and the PartialCachingCacheEntry
                fragment._cachedVaryId = cachedVary.CachedVaryId;
            }

            // Now insert into the cache (use cache provider if possible, otherwise use internal cache)
            if (!useProvider)
            {
                HttpRuntime.CacheInternal.UtcInsert(fragmentKey, fragment,
                                                    dependencies,
                                                    absExp, slidingExp,
                                                    CacheItemPriority.Normal,
                                                    null);
            }
            else
            {
                string depKey = null;
                if (dependencies != null)
                {
                    depKey = OUTPUTCACHE_KEYPREFIX_DEPENDENCIES + dependencies.GetUniqueID();
                    fragment._dependenciesKey = depKey;
                    fragment._dependencies    = dependencies.GetFileDependencies();
                }
                provider.Set(fragmentKey, fragment, absExp);
                if (dependencies != null)
                {
                    // use Add and dispose dependencies if there's already one in the cache
                    Object d = HttpRuntime.CacheInternal.UtcAdd(depKey, new DependencyCacheEntry(fragmentKey, null, provider.Name),
                                                                dependencies,
                                                                absExp, Cache.NoSlidingExpiration,
                                                                CacheItemPriority.Normal, s_dependencyRemovedCallbackForFragment);
                    if (d != null)
                    {
                        dependencies.Dispose();
                    }
                }
            }

#if DBG
            string cachedVaryType = (cachedVaryPutInCache) ? "ControlCachedVary" : "";
            string providerUsed   = (useProvider) ? provider.Name : "CacheInternal";
            Debug.Trace("OutputCache", "InsertFragment("
                        + cachedVaryKey + ", "
                        + cachedVaryType + ", "
                        + fragmentKey + ", PartialCachingCacheEntry, ...) -->"
                        + providerUsed);
#endif
        }
        internal void OnLeave(object source, EventArgs eventArgs)
        {
            HttpApplication application = (HttpApplication)source;
            HttpContext     context     = application.Context;
            HttpRequest     request     = context.Request;
            HttpResponse    response    = context.Response;
            HttpCachePolicy cache       = null;
            bool            flag        = false;

            if (response.HasCachePolicy)
            {
                cache = response.Cache;
                if (((cache.IsModified() && (response.Cookies.Count <= 0)) && (response.StatusCode == 200)) && (((request.HttpVerb == HttpVerb.GET) || (request.HttpVerb == HttpVerb.POST)) && response.IsBuffered()))
                {
                    bool flag3 = false;
                    if ((cache.GetCacheability() == HttpCacheability.Public) && context.RequestRequiresAuthorization())
                    {
                        cache.SetCacheability(HttpCacheability.Private);
                        flag3 = true;
                    }
                    if (((((cache.GetCacheability() == HttpCacheability.Public) || (cache.GetCacheability() == HttpCacheability.ServerAndPrivate)) || ((cache.GetCacheability() == HttpCacheability.Server) || flag3)) && (!cache.GetNoServerCaching() && (cache.HasExpirationPolicy() || cache.HasValidationPolicy()))) && ((!cache.VaryByHeaders.GetVaryByUnspecifiedParameters() && (cache.VaryByParams.AcceptsParams() || ((request.HttpVerb != HttpVerb.POST) && !request.HasQueryString))) && (!cache.VaryByContentEncodings.IsModified() || cache.VaryByContentEncodings.IsCacheableEncoding(context.Response.GetHttpHeaderContentEncoding()))))
                    {
                        flag = true;
                    }
                }
            }
            if (flag)
            {
                CachedVary vary;
                string     str;
                string[]   varyByParams;
                this.RecordCacheMiss();
                HttpCachePolicySettings currentSettings = cache.GetCurrentSettings(response);
                string[] varyByContentEncodings         = currentSettings.VaryByContentEncodings;
                string[] varyByHeaders = currentSettings.VaryByHeaders;
                if (currentSettings.IgnoreParams)
                {
                    varyByParams = null;
                }
                else
                {
                    varyByParams = currentSettings.VaryByParams;
                }
                if (this._key == null)
                {
                    this._key = this.CreateOutputCachedItemKey(context, null);
                }
                if (((varyByContentEncodings == null) && (varyByHeaders == null)) && ((varyByParams == null) && (currentSettings.VaryByCustom == null)))
                {
                    str  = this._key;
                    vary = null;
                }
                else
                {
                    int num;
                    int length;
                    if (varyByHeaders != null)
                    {
                        num    = 0;
                        length = varyByHeaders.Length;
                        while (num < length)
                        {
                            varyByHeaders[num] = "HTTP_" + CultureInfo.InvariantCulture.TextInfo.ToUpper(varyByHeaders[num].Replace('-', '_'));
                            num++;
                        }
                    }
                    bool varyByAllParams = false;
                    if (varyByParams != null)
                    {
                        varyByAllParams = (varyByParams.Length == 1) && (varyByParams[0] == "*");
                        if (varyByAllParams)
                        {
                            varyByParams = null;
                        }
                        else
                        {
                            num    = 0;
                            length = varyByParams.Length;
                            while (num < length)
                            {
                                varyByParams[num] = CultureInfo.InvariantCulture.TextInfo.ToLower(varyByParams[num]);
                                num++;
                            }
                        }
                    }
                    vary = new CachedVary(varyByContentEncodings, varyByHeaders, varyByParams, varyByAllParams, currentSettings.VaryByCustom);
                    str  = this.CreateOutputCachedItemKey(context, vary);
                    if (str == null)
                    {
                        return;
                    }
                    if (!response.IsBuffered())
                    {
                        return;
                    }
                }
                DateTime noAbsoluteExpiration = Cache.NoAbsoluteExpiration;
                TimeSpan noSlidingExpiration  = Cache.NoSlidingExpiration;
                if (currentSettings.SlidingExpiration)
                {
                    noSlidingExpiration = currentSettings.SlidingDelta;
                }
                else if (currentSettings.IsMaxAgeSet)
                {
                    DateTime time2 = (currentSettings.UtcTimestampCreated != DateTime.MinValue) ? currentSettings.UtcTimestampCreated : context.UtcTimestamp;
                    noAbsoluteExpiration = time2 + currentSettings.MaxAge;
                }
                else if (currentSettings.IsExpiresSet)
                {
                    noAbsoluteExpiration = currentSettings.UtcExpires;
                }
                if (noAbsoluteExpiration > DateTime.UtcNow)
                {
                    HttpRawResponse   snapshot       = response.GetSnapshot();
                    string            kernelCacheUrl = response.SetupKernelCaching(null);
                    Guid              cachedVaryId   = (vary != null) ? vary.CachedVaryId : Guid.Empty;
                    CachedRawResponse rawResponse    = new CachedRawResponse(snapshot, currentSettings, kernelCacheUrl, cachedVaryId);
                    CacheDependency   dependencies   = response.CreateCacheDependencyForResponse();
                    try
                    {
                        OutputCache.InsertResponse(this._key, vary, str, rawResponse, dependencies, noAbsoluteExpiration, noSlidingExpiration);
                    }
                    catch
                    {
                        if (dependencies != null)
                        {
                            dependencies.Dispose();
                        }
                        throw;
                    }
                }
                this._key = null;
            }
        }
        internal void OnEnter(object source, EventArgs eventArgs)
        {
            this._key = null;
            this._recordedCacheMiss = false;
            if (OutputCache.InUse)
            {
                string[]        strArray2   = null;
                string[]        strArray3   = null;
                HttpApplication application = (HttpApplication)source;
                HttpContext     context     = application.Context;
                context.GetFilePathData();
                HttpRequest  request  = context.Request;
                HttpResponse response = context.Response;
                switch (request.HttpVerb)
                {
                case HttpVerb.GET:
                case HttpVerb.HEAD:
                case HttpVerb.POST:
                {
                    string str;
                    this._key = str = this.CreateOutputCachedItemKey(context, null);
                    object obj2 = OutputCache.Get(str);
                    if (obj2 != null)
                    {
                        int        num;
                        int        length;
                        CachedVary cachedVary = obj2 as CachedVary;
                        if (cachedVary != null)
                        {
                            str = this.CreateOutputCachedItemKey(context, cachedVary);
                            if (str == null)
                            {
                                return;
                            }
                            if (cachedVary._contentEncodings == null)
                            {
                                obj2 = OutputCache.Get(str);
                            }
                            else
                            {
                                obj2 = null;
                                bool   flag3 = true;
                                string knownRequestHeader = context.WorkerRequest.GetKnownRequestHeader(0x16);
                                if (knownRequestHeader != null)
                                {
                                    string[] contentEncodings = cachedVary._contentEncodings;
                                    int      startIndex       = 0;
                                    bool     flag4            = false;
                                    while (!flag4)
                                    {
                                        flag4 = true;
                                        int index = GetAcceptableEncoding(contentEncodings, startIndex, knownRequestHeader);
                                        if (index > -1)
                                        {
                                            flag3 = false;
                                            obj2  = OutputCache.Get(str + contentEncodings[index]);
                                            if (obj2 == null)
                                            {
                                                startIndex = index + 1;
                                                if (startIndex < contentEncodings.Length)
                                                {
                                                    flag4 = false;
                                                }
                                            }
                                        }
                                        else if (index == -2)
                                        {
                                            flag3 = false;
                                        }
                                    }
                                }
                                if ((obj2 == null) && flag3)
                                {
                                    obj2 = OutputCache.Get(str);
                                }
                            }
                            if ((obj2 == null) || (((CachedRawResponse)obj2)._cachedVaryId != cachedVary.CachedVaryId))
                            {
                                if (obj2 != null)
                                {
                                    OutputCache.Remove(str, context);
                                }
                                return;
                            }
                        }
                        CachedRawResponse       response2 = (CachedRawResponse)obj2;
                        HttpCachePolicySettings settings  = response2._settings;
                        if ((cachedVary == null) && !settings.IgnoreParams)
                        {
                            if (request.HttpVerb == HttpVerb.POST)
                            {
                                this.RecordCacheMiss();
                                return;
                            }
                            if (request.HasQueryString)
                            {
                                this.RecordCacheMiss();
                                return;
                            }
                        }
                        if (settings.IgnoreRangeRequests)
                        {
                            string str8 = request.Headers["Range"];
                            if (StringUtil.StringStartsWithIgnoreCase(str8, "bytes"))
                            {
                                return;
                            }
                        }
                        if (!settings.HasValidationPolicy())
                        {
                            string str4 = request.Headers["Cache-Control"];
                            if (str4 != null)
                            {
                                strArray2 = str4.Split(s_fieldSeparators);
                                for (num = 0; num < strArray2.Length; num++)
                                {
                                    string str6 = strArray2[num];
                                    switch (str6)
                                    {
                                    case "no-cache":
                                    case "no-store":
                                        this.RecordCacheMiss();
                                        return;
                                    }
                                    if (StringUtil.StringStartsWith(str6, "max-age="))
                                    {
                                        int num4;
                                        try
                                        {
                                            num4 = Convert.ToInt32(str6.Substring(8), CultureInfo.InvariantCulture);
                                        }
                                        catch
                                        {
                                            num4 = -1;
                                        }
                                        if (num4 >= 0)
                                        {
                                            int num6 = (int)((context.UtcTimestamp.Ticks - settings.UtcTimestampCreated.Ticks) / 0x989680L);
                                            if (num6 >= num4)
                                            {
                                                this.RecordCacheMiss();
                                                return;
                                            }
                                        }
                                    }
                                    else if (StringUtil.StringStartsWith(str6, "min-fresh="))
                                    {
                                        int num5;
                                        try
                                        {
                                            num5 = Convert.ToInt32(str6.Substring(10), CultureInfo.InvariantCulture);
                                        }
                                        catch
                                        {
                                            num5 = -1;
                                        }
                                        if (((num5 >= 0) && settings.IsExpiresSet) && !settings.SlidingExpiration)
                                        {
                                            int num7 = (int)((settings.UtcExpires.Ticks - context.UtcTimestamp.Ticks) / 0x989680L);
                                            if (num7 < num5)
                                            {
                                                this.RecordCacheMiss();
                                                return;
                                            }
                                        }
                                    }
                                }
                            }
                            string str5 = request.Headers["Pragma"];
                            if (str5 != null)
                            {
                                strArray3 = str5.Split(s_fieldSeparators);
                                for (num = 0; num < strArray3.Length; num++)
                                {
                                    if (strArray3[num] == "no-cache")
                                    {
                                        this.RecordCacheMiss();
                                        return;
                                    }
                                }
                            }
                        }
                        else if (settings.ValidationCallbackInfo != null)
                        {
                            HttpValidationStatus valid             = HttpValidationStatus.Valid;
                            HttpValidationStatus ignoreThisRequest = valid;
                            num    = 0;
                            length = settings.ValidationCallbackInfo.Length;
                            while (num < length)
                            {
                                ValidationCallbackInfo info = settings.ValidationCallbackInfo[num];
                                try
                                {
                                    info.handler(context, info.data, ref valid);
                                }
                                catch (Exception exception)
                                {
                                    valid = HttpValidationStatus.Invalid;
                                    HttpApplicationFactory.RaiseError(exception);
                                }
                                switch (valid)
                                {
                                case HttpValidationStatus.Invalid:
                                    OutputCache.Remove(str, context);
                                    this.RecordCacheMiss();
                                    return;

                                case HttpValidationStatus.IgnoreThisRequest:
                                    ignoreThisRequest = HttpValidationStatus.IgnoreThisRequest;
                                    break;

                                case HttpValidationStatus.Valid:
                                    break;

                                default:
                                    valid = ignoreThisRequest;
                                    break;
                                }
                                num++;
                            }
                            if (ignoreThisRequest == HttpValidationStatus.IgnoreThisRequest)
                            {
                                this.RecordCacheMiss();
                                return;
                            }
                        }
                        HttpRawResponse rawResponse = response2._rawResponse;
                        if ((cachedVary == null) || (cachedVary._contentEncodings == null))
                        {
                            string    acceptEncoding  = request.Headers["Accept-Encoding"];
                            string    contentEncoding = null;
                            ArrayList headers         = rawResponse.Headers;
                            if (headers != null)
                            {
                                foreach (HttpResponseHeader header in headers)
                                {
                                    if (header.Name == "Content-Encoding")
                                    {
                                        contentEncoding = header.Value;
                                        break;
                                    }
                                }
                            }
                            if (!IsAcceptableEncoding(contentEncoding, acceptEncoding))
                            {
                                this.RecordCacheMiss();
                                return;
                            }
                        }
                        int num3 = -1;
                        if (!rawResponse.HasSubstBlocks)
                        {
                            string ifModifiedSince = request.IfModifiedSince;
                            if (ifModifiedSince != null)
                            {
                                num3 = 0;
                                try
                                {
                                    DateTime time = HttpDate.UtcParse(ifModifiedSince);
                                    if ((settings.IsLastModifiedSet && (settings.UtcLastModified <= time)) && (time <= context.UtcTimestamp))
                                    {
                                        num3 = 1;
                                    }
                                }
                                catch
                                {
                                }
                            }
                            if (num3 != 0)
                            {
                                string ifNoneMatch = request.IfNoneMatch;
                                if (ifNoneMatch != null)
                                {
                                    num3 = 0;
                                    string[] strArray = ifNoneMatch.Split(s_fieldSeparators);
                                    num    = 0;
                                    length = strArray.Length;
                                    while (num < length)
                                    {
                                        if ((num == 0) && strArray[num].Equals("*"))
                                        {
                                            num3 = 1;
                                            break;
                                        }
                                        if (strArray[num].Equals(settings.ETag))
                                        {
                                            num3 = 1;
                                            break;
                                        }
                                        num++;
                                    }
                                }
                            }
                        }
                        if (num3 == 1)
                        {
                            response.ClearAll();
                            response.StatusCode = 0x130;
                        }
                        else
                        {
                            bool sendBody = request.HttpVerb != HttpVerb.HEAD;
                            response.UseSnapshot(rawResponse, sendBody);
                        }
                        response.Cache.ResetFromHttpCachePolicySettings(settings, context.UtcTimestamp);
                        string originalCacheUrl = response2._kernelCacheUrl;
                        if (originalCacheUrl != null)
                        {
                            response.SetupKernelCaching(originalCacheUrl);
                        }
                        PerfCounters.IncrementCounter(AppPerfCounter.OUTPUT_CACHE_RATIO_BASE);
                        PerfCounters.IncrementCounter(AppPerfCounter.OUTPUT_CACHE_HITS);
                        this._key = null;
                        this._recordedCacheMiss = false;
                        application.CompleteRequest();
                        return;
                    }
                    return;
                }
                }
            }
        }