//
        // Actually computes the browser capabilities
        //
        internal HttpCapabilitiesBase Evaluate(HttpRequest request)
        {
            HttpCapabilitiesBase result;
            CacheInternal        cacheInternal = System.Web.HttpRuntime.CacheInternal;

            //
            // 1) grab UA and do optimistic cache lookup (if UA is in dependency list)
            //
            string userAgent         = GetUserAgent(request);
            string userAgentCacheKey = userAgent;

            // Use the shorten userAgent as the cache key.
            Debug.Assert(UserAgentCacheKeyLength != 0);
            // Trim the useragent string based on <browserCaps> config
            if (userAgentCacheKey != null && userAgentCacheKey.Length > UserAgentCacheKeyLength)
            {
                userAgentCacheKey = userAgentCacheKey.Substring(0, UserAgentCacheKeyLength);
            }

            bool   doFullCacheKeyLookup  = false;
            string optimisticCacheKey    = _cacheKeyPrefix + userAgentCacheKey;
            object optimisticCacheResult = cacheInternal.Get(optimisticCacheKey);

            // optimize for common case (desktop browser)
            result = optimisticCacheResult as HttpCapabilitiesBase;
            if (result != null)
            {
                return(result);
            }

            //
            // 1.1) optimistic cache entry could tell us to do full cache lookup
            //
            if (optimisticCacheResult == _disableOptimisticCachingSingleton)
            {
                doFullCacheKeyLookup = true;
            }
            else
            {
                // cache it and respect _cachetime
                result = EvaluateFinal(request, true);

                // Optimized cache key is disabled if the request matches any headers defined within identifications.
                if (result.UseOptimizedCacheKey)
                {
                    // Use the same browserCap result if one with the same capabilities can be found in the cache.
                    // This is to reduce the number of identical browserCap instances being cached.
                    CacheBrowserCapResult(ref result);

                    // Cache the result using the optimisicCacheKey
                    cacheInternal.UtcInsert(optimisticCacheKey, result, null, Cache.NoAbsoluteExpiration, _cachetime);

                    return(result);
                }
            }

            //
            // 2) either:
            //
            //      We've never seen the UA before (parse all headers to
            //          determine if the new UA also carries modile device
            //          httpheaders).
            //
            //      It's a mobile UA (so parse all headers) and do full
            //          cache lookup
            //
            //      UA isn't in dependency list (customer custom caps section)
            //

            IDictionaryEnumerator de = _variables.GetEnumerator();
            StringBuilder         sb = new StringBuilder(_cacheKeyPrefix);

            InternalSecurityPermissions.AspNetHostingPermissionLevelLow.Assert();

            while (de.MoveNext())
            {
                string key = (string)de.Key;
                string value;

                if (key.Length == 0)
                {
                    value = userAgent;
                }
                else
                {
                    value = request.ServerVariables[key];
                }

                if (value != null)
                {
                    sb.Append(value);
                }
            }

            CodeAccessPermission.RevertAssert();

            sb.Append(BrowserCapabilitiesFactoryBase.GetBrowserCapKey(BrowserCapFactory.InternalGetMatchedHeaders(), request));
            string fullCacheKey = sb.ToString();

            //
            // Only do full cache lookup if the optimistic cache
            // result was _disableOptimisticCachingSingleton or
            // if UserAgent wasn't in the cap var list.
            //
            if (userAgent == null || doFullCacheKeyLookup)
            {
                result = cacheInternal.Get(fullCacheKey) as HttpCapabilitiesBase;

                if (result != null)
                {
                    return(result);
                }
            }

            result = EvaluateFinal(request, false);

            // Use the same browserCap result if one with the same matched nodes can be found in the cache.
            // This is to reduce the number of identical browserCap instances being cached.
            CacheBrowserCapResult(ref result);

            // cache it and respect _cachetime
            cacheInternal.UtcInsert(fullCacheKey, result, null, Cache.NoAbsoluteExpiration, _cachetime);
            if (optimisticCacheKey != null)
            {
                cacheInternal.UtcInsert(optimisticCacheKey, _disableOptimisticCachingSingleton, null, Cache.NoAbsoluteExpiration, _cachetime);
            }

            return(result);
        }
Exemple #2
0
        internal HttpCapabilitiesBase Evaluate(HttpRequest request)
        {
            CacheInternal cacheInternal = HttpRuntime.CacheInternal;
            string        userAgent     = GetUserAgent(request);
            string        str2          = userAgent;

            if ((str2 != null) && (str2.Length > this.UserAgentCacheKeyLength))
            {
                str2 = str2.Substring(0, this.UserAgentCacheKeyLength);
            }
            bool   flag = false;
            string key  = this._cacheKeyPrefix + str2;
            object obj2 = cacheInternal.Get(key);
            HttpCapabilitiesBase result = obj2 as HttpCapabilitiesBase;

            if (result == null)
            {
                if (obj2 == _disableOptimisticCachingSingleton)
                {
                    flag = true;
                }
                else
                {
                    result = this.EvaluateFinal(request, true);
                    if (result.UseOptimizedCacheKey)
                    {
                        this.CacheBrowserCapResult(ref result);
                        cacheInternal.UtcInsert(key, result, null, Cache.NoAbsoluteExpiration, this._cachetime);
                        return(result);
                    }
                }
                IDictionaryEnumerator enumerator = this._variables.GetEnumerator();
                StringBuilder         builder    = new StringBuilder(this._cacheKeyPrefix);
                InternalSecurityPermissions.AspNetHostingPermissionLevelLow.Assert();
                while (enumerator.MoveNext())
                {
                    string str5;
                    string str4 = (string)enumerator.Key;
                    if (str4.Length == 0)
                    {
                        str5 = userAgent;
                    }
                    else
                    {
                        str5 = request.ServerVariables[str4];
                    }
                    if (str5 != null)
                    {
                        builder.Append(str5);
                    }
                }
                CodeAccessPermission.RevertAssert();
                builder.Append(BrowserCapabilitiesFactoryBase.GetBrowserCapKey(this.BrowserCapFactory.InternalGetMatchedHeaders(), request));
                string str6 = builder.ToString();
                if ((userAgent == null) || flag)
                {
                    result = cacheInternal.Get(str6) as HttpCapabilitiesBase;
                    if (result != null)
                    {
                        return(result);
                    }
                }
                result = this.EvaluateFinal(request, false);
                this.CacheBrowserCapResult(ref result);
                cacheInternal.UtcInsert(str6, result, null, Cache.NoAbsoluteExpiration, this._cachetime);
                if (key != null)
                {
                    cacheInternal.UtcInsert(key, _disableOptimisticCachingSingleton, null, Cache.NoAbsoluteExpiration, this._cachetime);
                }
            }
            return(result);
        }