コード例 #1
0
        //
        // callbacks
        //

        private static void HandleErrorWithoutContext(Exception e)
        {
            HttpApplicationFactory.RaiseError(e);
            try {
                WebBaseEvent.RaiseRuntimeError(e, typeof(OutputCache));
            }
            catch {
            }
        }
コード例 #2
0
 private void CallCacheItemRemovedCallback(CacheItemRemovedCallback callback, CacheItemRemovedReason reason)
 {
     if (base.IsPublic)
     {
         try
         {
             if (HttpContext.Current == null)
             {
                 using (new ApplicationImpersonationContext())
                 {
                     callback(base._key, this._value, reason);
                     return;
                 }
             }
             callback(base._key, this._value, reason);
         }
         catch (Exception exception)
         {
             HttpApplicationFactory.RaiseError(exception);
             try
             {
                 WebBaseEvent.RaiseRuntimeError(exception, this);
             }
             catch
             {
             }
         }
     }
     else
     {
         try
         {
             using (new ApplicationImpersonationContext())
             {
                 callback(base._key, this._value, reason);
             }
         }
         catch
         {
         }
     }
 }
コード例 #3
0
        /*
         * Helper to call the on-remove callback
         */

        private void CallCacheItemRemovedCallback(CacheItemRemovedCallback callback, CacheItemRemovedReason reason)
        {
            if (IsPublic)
            {
                try {
                    // for public need to impersonate if called outside of request context
                    if (HttpContext.Current == null)
                    {
                        using (new ApplicationImpersonationContext()) {
                            callback(_key, _value, reason);
                        }
                    }
                    else
                    {
                        callback(_key, _value, reason);
                    }
                }
                catch (Exception e) {
                    // for public need to report application error
                    HttpApplicationFactory.RaiseError(e);

                    try {
                        WebBaseEvent.RaiseRuntimeError(e, this);
                    }
                    catch {
                    }
                }
            }
            else
            {
                // for private items just make the call and eat any exceptions
                try {
                    using (new ApplicationImpersonationContext()) {
                        callback(_key, _value, reason);
                    }
                }
                catch {
                }
            }
        }
コード例 #4
0
        /*
         * Helper to call the on-remove callback
         */

        private void CallCacheItemRemovedCallback(CacheItemRemovedCallback callback, CacheItemRemovedReason reason)
        {
            if (IsPublic)
            {
                try {
                    // for public need to impersonate if called outside of request context
                    HttpContext.ImpersonationData impersonation = null;
                    if (HttpContext.Current == null)
                    {
                        impersonation = HttpContext.GetAppLevelImpersonation();
                        impersonation.Start(true /*forGlobalCode*/, false /*throwOnError*/);
                    }

                    try {
                        callback(_key, _value, reason);
                    }
                    finally {
                        if (impersonation != null)
                        {
                            impersonation.Stop();
                        }
                    }
                }
                catch (Exception e) {
                    // for public need to report application error
                    HttpApplicationFactory.RaiseError(e);
                }
            }
            else
            {
                // for private items just make the call and eat any exceptions
                try {
                    callback(_key, _value, reason);
                }
                catch {
                }
            }
        }
コード例 #5
0
        /*
         * Try to find this request in the cache. If so, return it. Otherwise,
         * store the cache key for use on Leave.
         */
        /// <include file='doc\OutputCacheModule.uex' path='docs/doc[@for="OutputCacheModule.OnEnter"]/*' />
        /// <devdoc>
        /// <para>Raises the <see langword='Enter'/>
        /// event, which searches the output cache for an item to satisfy the HTTP request. </para>
        /// </devdoc>
        internal /*public*/ void OnEnter(Object source, EventArgs eventArgs)
        {
            HttpApplication         app;
            HttpContext             context;
            string                  key;
            HttpRequest             request;
            HttpResponse            response;
            Object                  item;
            CachedRawResponse       cachedRawResponse;
            HttpCachePolicySettings settings;
            int  i, n;
            bool sendBody;
            HttpValidationStatus   validationStatus, validationStatusFinal;
            ValidationCallbackInfo callbackInfo;
            string   ifModifiedSinceHeader;
            DateTime utcIfModifiedSince;
            string   etag;

            string[] etags;
            int      send304;
            string   cacheControl;

            string[] cacheDirectives = null;
            string   pragma;

            string[]      pragmaDirectives = null;
            string        directive;
            int           maxage;
            int           minfresh;
            int           age;
            int           fresh;
            bool          hasValidationPolicy;
            CachedVary    cachedVary;
            CacheInternal cacheInternal;

            Debug.Trace("OutputCacheModuleEnter", "Beginning OutputCacheModule::Enter");

            app                = (HttpApplication)source;
            context            = app.Context;
            request            = context.Request;
            response           = context.Response;
            _key               = null;
            _recordedCacheMiss = false;
            _method            = CacheRequestMethod.Invalid;

            /*
             * Check if the request can be resolved for this method.
             */
            switch (request.HttpMethod)
            {
            case "HEAD":
                _method = CacheRequestMethod.Head;
                break;

            case "GET":
                _method = CacheRequestMethod.Get;
                break;

            case "POST":
                _method = CacheRequestMethod.Post;
                break;

            default:
                Debug.Trace("OutputCacheModuleEnter", "Output cache miss, Http method not GET, POST, or HEAD" +
                            "\nReturning from OutputCacheModule::Enter");

                return;
            }

            /*
             * Create a lookup key. Remember the key for use inside Leave()
             */
            _key = key = CreateOutputCachedItemKey(context, null);
            Debug.Assert(_key != null, "_key != null");

            /*
             *  Lookup the cached item.
             */
            cacheInternal = HttpRuntime.CacheInternal;
            item          = cacheInternal.Get(key);
            if (item == null)
            {
                Debug.Trace("OutputCacheModuleEnter", "Output cache miss, item not found.\n\tkey=" + key +
                            "\nReturning from OutputCacheModule::Enter");

                return;
            }

            cachedVary = item as CachedVary;
            if (cachedVary != null)
            {
                /*
                 * This cached output has a Vary policy. Create a new key based
                 * on the vary headers in cachedRawResponse and try again.
                 */
                Debug.Trace("OutputCacheModuleEnter", "Output cache found CachedVary, \n\tkey=" + key);
                key = CreateOutputCachedItemKey(context, cachedVary);
                if (key == null)
                {
                    Debug.Trace("OutputCacheModuleEnter", "Output cache miss, key could not be created for vary-by item." +
                                "\nReturning from OutputCacheModule::Enter");

                    return;
                }

                item = cacheInternal.Get(key);
                if (item == null)
                {
                    Debug.Trace("OutputCacheModuleEnter", "Output cache miss, item not found.\n\tkey=" + key +
                                "\nReturning from OutputCacheModule::Enter");

                    return;
                }
            }

            Debug.Assert(item.GetType() == typeof(CachedRawResponse), "item.GetType() == typeof(CachedRawResponse)");
            cachedRawResponse = (CachedRawResponse)item;
            settings          = cachedRawResponse._settings;
            if (cachedVary == null && !settings.IgnoreParams)
            {
                /*
                 * This cached output has no vary policy, so make sure it doesn't have a query string or form post.
                 */
                if (_method == CacheRequestMethod.Post)
                {
                    Debug.Trace("OutputCacheModuleEnter", "Output cache item found but method is POST and no VaryByParam specified." +
                                "\n\tkey=" + key +
                                "\nReturning from OutputCacheModule::Enter");
                    RecordCacheMiss();
                    return;
                }

                string queryStringText = request.QueryStringText;
                if (queryStringText != null && queryStringText.Length > 0)
                {
                    Debug.Trace("OutputCacheModuleEnter", "Output cache item found but contains a querystring and no VaryByParam specified." +
                                "\n\tkey=" + key +
                                "\nReturning from OutputCacheModule::Enter");
                    RecordCacheMiss();
                    return;
                }
            }

            hasValidationPolicy = settings.HasValidationPolicy();

            /*
             * Determine whether the client can accept a cached copy, and
             * get values of other cache control directives.
             *
             * We do this after lookup so we don't have to crack the headers
             * if the item is not found. Cracking the headers is expensive.
             */
            if (!hasValidationPolicy)
            {
                cacheControl = request.Headers["Cache-Control"];
                if (cacheControl != null)
                {
                    cacheDirectives = cacheControl.Split(s_fieldSeparators);
                    for (i = 0; i < cacheDirectives.Length; i++)
                    {
                        directive = cacheDirectives[i];
                        if (directive == "no-cache")
                        {
                            Debug.Trace("OutputCacheModuleEnter",
                                        "Skipping lookup because of Cache-Control: no-cache directive." +
                                        "\nReturning from OutputCacheModule::Enter");

                            RecordCacheMiss();
                            return;
                        }

                        if (directive.StartsWith("max-age="))
                        {
                            try {
                                maxage = Convert.ToInt32(directive.Substring(8));
                            }
                            catch {
                                maxage = -1;
                            }

                            if (maxage >= 0)
                            {
                                age = (int)((context.UtcTimestamp.Ticks - settings.UtcTimestampCreated.Ticks) / TimeSpan.TicksPerSecond);
                                if (age >= maxage)
                                {
                                    Debug.Trace("OutputCacheModuleEnter",
                                                "Not returning found item due to Cache-Control: max-age directive." +
                                                "\nReturning from OutputCacheModule::Enter");

                                    RecordCacheMiss();
                                    return;
                                }
                            }
                        }
                        else if (directive.StartsWith("min-fresh="))
                        {
                            try {
                                minfresh = Convert.ToInt32(directive.Substring(10));
                            }
                            catch {
                                minfresh = -1;
                            }

                            if (minfresh >= 0 && settings.IsExpiresSet && !settings.SlidingExpiration)
                            {
                                fresh = (int)((settings.UtcExpires.Ticks - context.UtcTimestamp.Ticks) / TimeSpan.TicksPerSecond);
                                if (fresh < minfresh)
                                {
                                    Debug.Trace("OutputCacheModuleEnter",
                                                "Not returning found item due to Cache-Control: min-fresh directive." +
                                                "\nReturning from OutputCacheModule::Enter");

                                    RecordCacheMiss();
                                    return;
                                }
                            }
                        }
                    }
                }

                pragma = request.Headers["Pragma"];
                if (pragma != null)
                {
                    pragmaDirectives = pragma.Split(s_fieldSeparators);
                    for (i = 0; i < pragmaDirectives.Length; i++)
                    {
                        if (pragmaDirectives[i] == "no-cache")
                        {
                            Debug.Trace("OutputCacheModuleEnter",
                                        "Skipping lookup because of Pragma: no-cache directive." +
                                        "\nReturning from OutputCacheModule::Enter");

                            RecordCacheMiss();
                            return;
                        }
                    }
                }
            }
            else if (settings.ValidationCallbackInfo != null)
            {
                /*
                 * Check if the item is still valid.
                 */
                validationStatus      = HttpValidationStatus.Valid;
                validationStatusFinal = validationStatus;
                for (i = 0, n = settings.ValidationCallbackInfo.Length; i < n; i++)
                {
                    callbackInfo = settings.ValidationCallbackInfo[i];
                    try {
                        callbackInfo.handler(context, callbackInfo.data, ref validationStatus);
                    }
                    catch (Exception e) {
                        validationStatus = HttpValidationStatus.Invalid;
                        HttpApplicationFactory.RaiseError(e);
                    }

                    switch (validationStatus)
                    {
                    case HttpValidationStatus.Invalid:
                        Debug.Trace("OutputCacheModuleEnter", "Output cache item found but callback invalidated it." +
                                    "\n\tkey=" + key +
                                    "\nReturning from OutputCacheModule::Enter");

                        cacheInternal.Remove(key);
                        RecordCacheMiss();
                        return;

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

                    case HttpValidationStatus.Valid:
                        break;

                    default:
                        Debug.Trace("OutputCacheModuleEnter", "Invalid validation status, ignoring it, status=" + validationStatus +
                                    "\n\tkey=" + key);

                        validationStatus = validationStatusFinal;
                        break;
                    }
                }

                if (validationStatusFinal == HttpValidationStatus.IgnoreThisRequest)
                {
                    Debug.Trace("OutputCacheModuleEnter", "Output cache item found but callback status is IgnoreThisRequest." +
                                "\n\tkey=" + key +
                                "\nReturning from OutputCacheModule::Enter");


                    RecordCacheMiss();
                    return;
                }

                Debug.Assert(validationStatusFinal == HttpValidationStatus.Valid,
                             "validationStatusFinal == HttpValidationStatus.Valid");
            }

            /*
             * Try to satisfy a conditional request. The cached response
             * must satisfy all conditions that are present.
             *
             * We can only satisfy a conditional request if the response
             * is buffered and has no substitution blocks.
             *
             * N.B. RFC 2616 says conditional requests only occur
             * with the GET method, but we try to satisfy other
             * verbs (HEAD, POST) as well.
             */
            send304 = -1;

            if (response.IsBuffered() && !cachedRawResponse._rawResponse.HasSubstBlocks)
            {
                /* Check "If-Modified-Since" header */
                ifModifiedSinceHeader = request.IfModifiedSince;
                if (ifModifiedSinceHeader != null)
                {
                    send304 = 0;
                    try {
                        utcIfModifiedSince = HttpDate.UtcParse(ifModifiedSinceHeader);
                        if (settings.IsLastModifiedSet &&
                            settings.UtcLastModified <= utcIfModifiedSince &&
                            utcIfModifiedSince <= context.UtcTimestamp)
                        {
                            send304 = 1;
                        }
                    }
                    catch {
                        Debug.Trace("OutputCacheModuleEnter", "Ignore If-Modified-Since header, invalid format: " + ifModifiedSinceHeader);
                    }
                }

                /* Check "If-None-Match" header */
                if (send304 != 0)
                {
                    etag = request.IfNoneMatch;
                    if (etag != null)
                    {
                        send304 = 0;
                        etags   = etag.Split(s_fieldSeparators);
                        for (i = 0, n = etags.Length; i < n; i++)
                        {
                            if (i == 0 && etags[i].Equals("*"))
                            {
                                send304 = 1;
                                break;
                            }

                            if (etags[i].Equals(settings.ETag))
                            {
                                send304 = 1;
                                break;
                            }
                        }
                    }
                }
            }

            if (send304 == 1)
            {
                /*
                 * Send 304 Not Modified
                 */
                Debug.Trace("OutputCacheModuleEnter", "Output cache hit & conditional request satisfied, status=304." +
                            "\n\tkey=" + key +
                            "\nReturning from OutputCacheModule::Enter");

                response.ClearAll();
                response.StatusCode = 304;
            }
            else
            {
                /*
                 * Send the full response.
                 */
#if DBG
                if (send304 == -1)
                {
                    Debug.Trace("OutputCacheModuleEnter", "Output cache hit.\n\tkey=" + key +
                                "\nReturning from OutputCacheModule::Enter");
                }
                else
                {
                    Debug.Trace("OutputCacheModuleEnter", "Output cache hit but conditional request not satisfied.\n\tkey=" + key +
                                "\nReturning from OutputCacheModule::Enter");
                }
#endif

                sendBody = (_method != CacheRequestMethod.Head);

                // UseSnapshot calls ClearAll
                response.UseSnapshot(cachedRawResponse._rawResponse, sendBody);
            }

            response.Cache.ResetFromHttpCachePolicySettings(settings, context.UtcTimestamp);

            PerfCounters.IncrementCounter(AppPerfCounter.OUTPUT_CACHE_RATIO_BASE);
            PerfCounters.IncrementCounter(AppPerfCounter.OUTPUT_CACHE_HITS);

            _key = null;
            _recordedCacheMiss = false;
            _method            = CacheRequestMethod.Invalid;

            app.CompleteRequest();
        }
コード例 #6
0
        internal static string CreateOutputCachedItemKey(
            string path,
            CacheRequestMethod method,
            HttpContext context,
            CachedVary cachedVary)
        {
            StringBuilder sb;
            int           i, j, n;
            string        name, value;

            string[]            a;
            byte[]              buf, hash;
            HttpRequest         request;
            NameValueCollection col;
            int contentLength;

            if (method == CacheRequestMethod.Post)
            {
                sb = new StringBuilder("System.Web.Http.HttpRawResponse\nM=3\n");
            }
            else
            {
                sb = new StringBuilder("System.Web.Http.HttpRawResponse\nM=2\n");
            }

            sb.Append(CultureInfo.InvariantCulture.TextInfo.ToLower(path));

            /* key for cached vary item has additional information */
            if (cachedVary != null)
            {
                request = context.Request;

                /* params part */
                for (j = 0; j <= 2; j++)
                {
                    switch (j)
                    {
                    case 0:
                        sb.Append("\nVH");
                        a   = cachedVary._headers;
                        col = request.ServerVariables;
                        break;

                    case 1:
                        sb.Append("\nVPQ");
                        a   = cachedVary._params;
                        col = request.QueryString;
                        break;

                    case 2:
                    default:
                        sb.Append("\nVPF");
                        a   = cachedVary._params;
                        col = request.Form;
                        if (method != CacheRequestMethod.Post)
                        {
                            col = null;
                        }

                        break;
                    }

                    if (col == null)
                    {
                        continue;
                    }

                    /* handle all params case (VaryByParams[*] = true) */
                    if (a == null && cachedVary._varyByAllParams && j != 0)
                    {
                        a = col.AllKeys;
                        for (i = a.Length - 1; i >= 0; i--)
                        {
                            if (a[i] != null)
                            {
                                a[i] = CultureInfo.InvariantCulture.TextInfo.ToLower(a[i]);
                            }
                        }

                        Array.Sort(a, InvariantComparer.Default);
                    }

                    if (a != null)
                    {
                        for (i = 0, n = a.Length; i < n; i++)
                        {
                            name  = a[i];
                            value = col[name];
                            if (value == null)
                            {
                                value = NULL_VARYBY_VALUE;
                            }

                            sb.Append("\tPN:");
                            sb.Append(name);
                            sb.Append("\tPV:");
                            sb.Append(value);
                        }
                    }
                }

                /* custom string part */
                sb.Append("\nVC");
                if (cachedVary._varyByCustom != null)
                {
                    sb.Append("\tCN:");
                    sb.Append(cachedVary._varyByCustom);
                    sb.Append("\tCV:");

                    try {
                        value = context.ApplicationInstance.GetVaryByCustomString(
                            context, cachedVary._varyByCustom);
                        if (value == null)
                        {
                            value = NULL_VARYBY_VALUE;
                        }
                    }
                    catch (Exception e) {
                        value = ERROR_VARYBY_VALUE;
                        HttpApplicationFactory.RaiseError(e);
                    }

                    sb.Append(value);
                }

                /*
                 * if VaryByParms=*, and method is not a form, then
                 * use a cryptographically strong hash of the data as
                 * part of the key.
                 */
                sb.Append("\nVPD");
                if (method == CacheRequestMethod.Post &&
                    cachedVary._varyByAllParams &&
                    request.Form.Count == 0)
                {
                    contentLength = request.ContentLength;
                    if (contentLength > MAX_POST_KEY_LENGTH || contentLength < 0)
                    {
                        return(null);
                    }

                    if (contentLength > 0)
                    {
                        buf = ((HttpInputStream)request.InputStream).Data;
                        if (buf == null)
                        {
                            return(null);
                        }

                        hash  = MachineKey.HashData(buf, s_hashModifier, 0, buf.Length);
                        value = Convert.ToBase64String(hash);
                        sb.Append(value);
                    }
                }

                sb.Append("\nEOV");
            }

            return(sb.ToString());
        }
コード例 #7
0
        internal static string CreateOutputCachedItemKey(string path, HttpVerb verb, HttpContext context, CachedVary cachedVary)
        {
            StringBuilder builder;

            if (verb == HttpVerb.POST)
            {
                builder = new StringBuilder("a1", path.Length + "a1".Length);
            }
            else
            {
                builder = new StringBuilder("a2", path.Length + "a2".Length);
            }
            builder.Append(CultureInfo.InvariantCulture.TextInfo.ToLower(path));
            if (cachedVary != null)
            {
                string      varyByCustomString;
                HttpRequest request = context.Request;
                for (int i = 0; i <= 2; i++)
                {
                    int                 num;
                    string[]            array = null;
                    NameValueCollection serverVarsWithoutDemand = null;
                    bool                flag = false;
                    switch (i)
                    {
                    case 0:
                        builder.Append("H");
                        array = cachedVary._headers;
                        if (array != null)
                        {
                            serverVarsWithoutDemand = request.GetServerVarsWithoutDemand();
                        }
                        break;

                    case 1:
                        builder.Append("Q");
                        array = cachedVary._params;
                        if (request.HasQueryString && ((array != null) || cachedVary._varyByAllParams))
                        {
                            serverVarsWithoutDemand = request.QueryString;
                            flag = cachedVary._varyByAllParams;
                        }
                        break;

                    default:
                        builder.Append("F");
                        if (verb == HttpVerb.POST)
                        {
                            array = cachedVary._params;
                            if (request.HasForm && ((array != null) || cachedVary._varyByAllParams))
                            {
                                serverVarsWithoutDemand = request.Form;
                                flag = cachedVary._varyByAllParams;
                            }
                        }
                        break;
                    }
                    if (flag && (serverVarsWithoutDemand.Count > 0))
                    {
                        array = serverVarsWithoutDemand.AllKeys;
                        num   = array.Length - 1;
                        while (num >= 0)
                        {
                            if (array[num] != null)
                            {
                                array[num] = CultureInfo.InvariantCulture.TextInfo.ToLower(array[num]);
                            }
                            num--;
                        }
                        Array.Sort(array, System.InvariantComparer.Default);
                    }
                    if (array != null)
                    {
                        num = 0;
                        int length = array.Length;
                        while (num < length)
                        {
                            string str = array[num];
                            if (serverVarsWithoutDemand == null)
                            {
                                varyByCustomString = "+n+";
                            }
                            else
                            {
                                varyByCustomString = serverVarsWithoutDemand[str];
                                if (varyByCustomString == null)
                                {
                                    varyByCustomString = "+n+";
                                }
                            }
                            builder.Append("N");
                            builder.Append(str);
                            builder.Append("V");
                            builder.Append(varyByCustomString);
                            num++;
                        }
                    }
                }
                builder.Append("C");
                if (cachedVary._varyByCustom != null)
                {
                    builder.Append("N");
                    builder.Append(cachedVary._varyByCustom);
                    builder.Append("V");
                    try
                    {
                        varyByCustomString = context.ApplicationInstance.GetVaryByCustomString(context, cachedVary._varyByCustom);
                        if (varyByCustomString == null)
                        {
                            varyByCustomString = "+n+";
                        }
                    }
                    catch (Exception exception)
                    {
                        varyByCustomString = "+e+";
                        HttpApplicationFactory.RaiseError(exception);
                    }
                    builder.Append(varyByCustomString);
                }
                builder.Append("D");
                if (((verb == HttpVerb.POST) && cachedVary._varyByAllParams) && (request.Form.Count == 0))
                {
                    int contentLength = request.ContentLength;
                    if ((contentLength > 0x3a98) || (contentLength < 0))
                    {
                        return(null);
                    }
                    if (contentLength > 0)
                    {
                        byte[] asByteArray = ((HttpInputStream)request.InputStream).GetAsByteArray();
                        if (asByteArray == null)
                        {
                            return(null);
                        }
                        varyByCustomString = Convert.ToBase64String(MachineKeySection.HashData(asByteArray, null, 0, asByteArray.Length));
                        builder.Append(varyByCustomString);
                    }
                }
                builder.Append("E");
                string[] strArray2 = cachedVary._contentEncodings;
                if (strArray2 != null)
                {
                    string httpHeaderContentEncoding = context.Response.GetHttpHeaderContentEncoding();
                    if (httpHeaderContentEncoding != null)
                    {
                        for (int j = 0; j < strArray2.Length; j++)
                        {
                            if (strArray2[j] == httpHeaderContentEncoding)
                            {
                                builder.Append(httpHeaderContentEncoding);
                                break;
                            }
                        }
                    }
                }
            }
            return(builder.ToString());
        }
コード例 #8
0
        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;
                }
                }
            }
        }