//generate the code from the parsed BrowserDefinitionTree
        //compile it, and install it in the gac
        internal void GenerateCode(AssemblyBuilder assemblyBuilder) {
            
            ProcessBrowserFiles(true /*useVirtualPath*/, BrowserCapabilitiesCompiler.AppBrowsersVirtualDir.VirtualPathString);
            ProcessCustomBrowserFiles(true /*useVirtualPath*/, BrowserCapabilitiesCompiler.AppBrowsersVirtualDir.VirtualPathString);
            
            CodeCompileUnit ccu = new CodeCompileUnit();

            Debug.Assert(BrowserTree != null);
            ArrayList customTreeRoots = new ArrayList();
            for (int i = 0; i < CustomTreeNames.Count; i++) {
                customTreeRoots.Add((BrowserDefinition)(((BrowserTree)CustomTreeList[i])[CustomTreeNames[i]]));
            }

            // namespace ASP
            CodeNamespace cnamespace = new CodeNamespace(BaseCodeDomTreeGenerator.defaultNamespace);
            //GEN: using System;
            cnamespace.Imports.Add(new CodeNamespaceImport("System"));
            //GEN: using System.Web;
            cnamespace.Imports.Add(new CodeNamespaceImport("System.Web"));
            //GEN: using System.Web.Configuration;
            cnamespace.Imports.Add(new CodeNamespaceImport("System.Web.Configuration"));
            //GEN: using System.Reflection;
            cnamespace.Imports.Add(new CodeNamespaceImport("System.Reflection"));
            //GEN: class BrowserCapabilitiesFactory
            ccu.Namespaces.Add(cnamespace);

            Type baseType = BrowserCapabilitiesCompiler.GetBrowserCapabilitiesFactoryBaseType();

            CodeTypeDeclaration factoryType = new CodeTypeDeclaration();
            factoryType.Attributes = MemberAttributes.Private;
            factoryType.IsClass = true;
            factoryType.Name = TypeName;
            factoryType.BaseTypes.Add(new CodeTypeReference(baseType));
            cnamespace.Types.Add(factoryType);

            BindingFlags flags = BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.NonPublic;

            BrowserDefinition bd = null;
            //GEN: protected override object ConfigureBrowserCapabilities(NameValueCollection headers, HttpBrowserCapabilities browserCaps)
            CodeMemberMethod method = new CodeMemberMethod();
            method.Attributes = MemberAttributes.Override | MemberAttributes.Public;
            method.ReturnType = new CodeTypeReference(typeof(void));
            method.Name = "ConfigureCustomCapabilities";
            CodeParameterDeclarationExpression cpde = new CodeParameterDeclarationExpression(typeof(NameValueCollection), "headers");
            method.Parameters.Add(cpde);
            cpde = new CodeParameterDeclarationExpression(typeof(HttpBrowserCapabilities), "browserCaps");
            method.Parameters.Add(cpde);
            factoryType.Members.Add(method);

            for (int i = 0; i < customTreeRoots.Count; i++) {
                GenerateSingleProcessCall((BrowserDefinition)customTreeRoots[i], method);
            }
            
            foreach (DictionaryEntry entry in _browserOverrides) {
                object key = entry.Key;
                BrowserDefinition firstBrowserDefinition = (BrowserDefinition)BrowserTree[GetFirstItemFromKey(_browserOverrides, key)];
                
                string parentName = firstBrowserDefinition.ParentName;
                
                //



                if ((!TargetFrameworkUtil.HasMethod(baseType, parentName + "ProcessBrowsers", flags)) ||
                    (!TargetFrameworkUtil.HasMethod(baseType, parentName + "ProcessGateways", flags))) {
                    String parentID = firstBrowserDefinition.ParentID;

                    if (firstBrowserDefinition != null) {
                        throw new ConfigurationErrorsException(SR.GetString(SR.Browser_parentID_Not_Found, parentID), firstBrowserDefinition.XmlNode);
                    } else {
                        throw new ConfigurationErrorsException(SR.GetString(SR.Browser_parentID_Not_Found, parentID));
                    }
                }
               
                bool isBrowserDefinition = true;
                if (firstBrowserDefinition is GatewayDefinition) {
                    isBrowserDefinition = false;
                }

                //GenerateMethodsToOverrideBrowsers
                //Gen: protected override void Xxx_ProcessChildBrowsers(bool ignoreApplicationBrowsers, MNameValueCollection headers, HttpBrowserCapabilities browserCaps) ;

                string methodName = parentName + (isBrowserDefinition ? "ProcessBrowsers" : "ProcessGateways");
                CodeMemberMethod cmm = new CodeMemberMethod();
                cmm.Name = methodName;
                cmm.ReturnType = new CodeTypeReference(typeof(void));
                cmm.Attributes = MemberAttributes.Family | MemberAttributes.Override;

                if (isBrowserDefinition) {
                    cpde = new CodeParameterDeclarationExpression(typeof(bool), BrowserCapabilitiesCodeGenerator.IgnoreApplicationBrowserVariableName);
                    cmm.Parameters.Add(cpde);
                }
                cpde = new CodeParameterDeclarationExpression(typeof(NameValueCollection), "headers");
                cmm.Parameters.Add(cpde);
                cpde = new CodeParameterDeclarationExpression(typeof(HttpBrowserCapabilities), browserCapsVariable);
                cmm.Parameters.Add(cpde);

                factoryType.Members.Add(cmm);

                ArrayList overrides = (ArrayList)_browserOverrides[key];
                CodeStatementCollection statements = cmm.Statements;

                bool ignoreApplicationBrowsersVarRefGenerated = false;
                
                foreach (string browserID in overrides) {
                    bd = (BrowserDefinition)BrowserTree[browserID];
                    if (bd is GatewayDefinition || bd.IsRefID) {
                        GenerateSingleProcessCall(bd, cmm);
                    }
                    else {
                        if (!ignoreApplicationBrowsersVarRefGenerated) {
                            Debug.Assert(isBrowserDefinition);

                            // Gen: if (ignoreApplicationBrowsers) {
                            //      }
                            //      else {
                            //          ...
                            //      }
                            CodeConditionStatement istatement = new CodeConditionStatement();

                            istatement.Condition = new CodeVariableReferenceExpression(BrowserCapabilitiesCodeGenerator.IgnoreApplicationBrowserVariableName);

                            cmm.Statements.Add(istatement);
                            statements = istatement.FalseStatements;

                            ignoreApplicationBrowsersVarRefGenerated = true;
                        }
                        statements = GenerateTrackedSingleProcessCall(statements, bd, cmm);
                        if (_baseInstance == null) {
                            // If we are targeting 4.0 or using the ASP.BrowserCapsFactory assembly generated by
                            // aspnet_regbrowsers.exe, we can simply just instantiate the type.
                            // If not, then we need to use the type BrowserCapabilitiesFactory35 that contains code
                            // from the 2.0 version of BrowserCapabilitiesFactory. This is because "baseType" is the 4.0 type
                            // that contains the new 4.0 definitions.
                            // (Dev10 bug 795509)
                            if (MultiTargetingUtil.IsTargetFramework40OrAbove || 
                                baseType.Assembly == BrowserCapabilitiesCompiler.AspBrowserCapsFactoryAssembly) {
                                _baseInstance = (BrowserCapabilitiesFactoryBase)Activator.CreateInstance(baseType);
                            }
                            else {
                                _baseInstance = new BrowserCapabilitiesFactory35();
                            }
                        }
                        int parentDepth = (int)((Triplet)_baseInstance.InternalGetBrowserElements()[parentName]).Third;
                        AddBrowserToCollectionRecursive(bd, parentDepth + 1);
                    }
                }

            }

            foreach (DictionaryEntry entry in _defaultBrowserOverrides) {
                object key = entry.Key;

                BrowserDefinition firstDefaultBrowserDefinition = (BrowserDefinition)DefaultTree[GetFirstItemFromKey(_defaultBrowserOverrides, key)];
                string parentName = firstDefaultBrowserDefinition.ParentName;

                if (baseType.GetMethod("Default" + parentName + "ProcessBrowsers", flags) == null) {
                    String parentID = firstDefaultBrowserDefinition.ParentID;
                    if (firstDefaultBrowserDefinition != null) {
                        throw new ConfigurationErrorsException(SR.GetString(SR.DefaultBrowser_parentID_Not_Found, parentID), firstDefaultBrowserDefinition.XmlNode);
                    }
                }

                string methodName = "Default" + parentName + "ProcessBrowsers";
                CodeMemberMethod cmm = new CodeMemberMethod();
                cmm.Name = methodName;
                cmm.ReturnType = new CodeTypeReference(typeof(void));
                cmm.Attributes = MemberAttributes.Family | MemberAttributes.Override;
                cpde = new CodeParameterDeclarationExpression(typeof(bool), BrowserCapabilitiesCodeGenerator.IgnoreApplicationBrowserVariableName);
                cmm.Parameters.Add(cpde);
                cpde = new CodeParameterDeclarationExpression(typeof(NameValueCollection), "headers");
                cmm.Parameters.Add(cpde);
                cpde = new CodeParameterDeclarationExpression(typeof(HttpBrowserCapabilities), browserCapsVariable);
                cmm.Parameters.Add(cpde);
                factoryType.Members.Add(cmm);

                ArrayList overrides = (ArrayList)_defaultBrowserOverrides[key];

                CodeConditionStatement istatement = new CodeConditionStatement();
                istatement.Condition = new CodeVariableReferenceExpression(BrowserCapabilitiesCodeGenerator.IgnoreApplicationBrowserVariableName);

                cmm.Statements.Add(istatement);
                CodeStatementCollection statements = istatement.FalseStatements;

                foreach(string browserID in overrides) {
                    bd = (BrowserDefinition)DefaultTree[browserID];
                    Debug.Assert(!(bd is GatewayDefinition));

                    if(bd.IsRefID) {
                        GenerateSingleProcessCall(bd, cmm, "Default");
                    }
                    else {
                        statements = GenerateTrackedSingleProcessCall(statements, bd, cmm, "Default");
                    }
                }
            }

            // Generate process method for the browser elements
            foreach (DictionaryEntry entry in BrowserTree) {
                bd = entry.Value as BrowserDefinition;
                Debug.Assert(bd != null);
                GenerateProcessMethod(bd, factoryType);
            }

            for (int i = 0; i < customTreeRoots.Count; i++) {
                foreach (DictionaryEntry entry in (BrowserTree)CustomTreeList[i]) {
                    bd = entry.Value as BrowserDefinition;
                    Debug.Assert(bd != null);
                    GenerateProcessMethod(bd, factoryType);
                }
            }

            // Generate process method for the default browser elements
            foreach (DictionaryEntry entry in DefaultTree) {
                bd = entry.Value as BrowserDefinition;
                Debug.Assert(bd != null);
                GenerateProcessMethod(bd, factoryType, "Default");
            }
            GenerateOverrideMatchedHeaders(factoryType);
            GenerateOverrideBrowserElements(factoryType);

            Assembly assembly = BrowserCapabilitiesCompiler.GetBrowserCapabilitiesFactoryBaseType().Assembly;
            assemblyBuilder.AddAssemblyReference(assembly, ccu);
            assemblyBuilder.AddCodeCompileUnit(_buildProvider, ccu);
        }
 internal void GenerateCode(AssemblyBuilder assemblyBuilder)
 {
     base.ProcessBrowserFiles(true, BrowserCapabilitiesCompiler.AppBrowsersVirtualDir.VirtualPathString);
     base.ProcessCustomBrowserFiles(true, BrowserCapabilitiesCompiler.AppBrowsersVirtualDir.VirtualPathString);
     CodeCompileUnit ccu = new CodeCompileUnit();
     ArrayList list = new ArrayList();
     for (int i = 0; i < base.CustomTreeNames.Count; i++)
     {
         list.Add((BrowserDefinition) ((BrowserTree) base.CustomTreeList[i])[base.CustomTreeNames[i]]);
     }
     CodeNamespace namespace2 = new CodeNamespace("ASP");
     namespace2.Imports.Add(new CodeNamespaceImport("System"));
     namespace2.Imports.Add(new CodeNamespaceImport("System.Web"));
     namespace2.Imports.Add(new CodeNamespaceImport("System.Web.Configuration"));
     namespace2.Imports.Add(new CodeNamespaceImport("System.Reflection"));
     ccu.Namespaces.Add(namespace2);
     Type browserCapabilitiesFactoryBaseType = BrowserCapabilitiesCompiler.GetBrowserCapabilitiesFactoryBaseType();
     CodeTypeDeclaration declaration = new CodeTypeDeclaration {
         Attributes = MemberAttributes.Private,
         IsClass = true,
         Name = this.TypeName
     };
     declaration.BaseTypes.Add(new CodeTypeReference(browserCapabilitiesFactoryBaseType));
     namespace2.Types.Add(declaration);
     BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase;
     BrowserDefinition bd = null;
     CodeMemberMethod method = new CodeMemberMethod {
         Attributes = MemberAttributes.Public | MemberAttributes.Override,
         ReturnType = new CodeTypeReference(typeof(void)),
         Name = "ConfigureCustomCapabilities"
     };
     CodeParameterDeclarationExpression expression = new CodeParameterDeclarationExpression(typeof(NameValueCollection), "headers");
     method.Parameters.Add(expression);
     expression = new CodeParameterDeclarationExpression(typeof(HttpBrowserCapabilities), "browserCaps");
     method.Parameters.Add(expression);
     declaration.Members.Add(method);
     for (int j = 0; j < list.Count; j++)
     {
         base.GenerateSingleProcessCall((BrowserDefinition) list[j], method);
     }
     foreach (DictionaryEntry entry in this._browserOverrides)
     {
         object key = entry.Key;
         BrowserDefinition definition2 = (BrowserDefinition) base.BrowserTree[GetFirstItemFromKey(this._browserOverrides, key)];
         string parentName = definition2.ParentName;
         if (!TargetFrameworkUtil.HasMethod(browserCapabilitiesFactoryBaseType, parentName + "ProcessBrowsers", bindingAttr) || !TargetFrameworkUtil.HasMethod(browserCapabilitiesFactoryBaseType, parentName + "ProcessGateways", bindingAttr))
         {
             string parentID = definition2.ParentID;
             if (definition2 != null)
             {
                 throw new ConfigurationErrorsException(System.Web.SR.GetString("Browser_parentID_Not_Found", new object[] { parentID }), definition2.XmlNode);
             }
             throw new ConfigurationErrorsException(System.Web.SR.GetString("Browser_parentID_Not_Found", new object[] { parentID }));
         }
         bool flag = true;
         if (definition2 is GatewayDefinition)
         {
             flag = false;
         }
         string str3 = parentName + (flag ? "ProcessBrowsers" : "ProcessGateways");
         CodeMemberMethod method2 = new CodeMemberMethod {
             Name = str3,
             ReturnType = new CodeTypeReference(typeof(void)),
             Attributes = MemberAttributes.Family | MemberAttributes.Override
         };
         if (flag)
         {
             expression = new CodeParameterDeclarationExpression(typeof(bool), "ignoreApplicationBrowsers");
             method2.Parameters.Add(expression);
         }
         expression = new CodeParameterDeclarationExpression(typeof(NameValueCollection), "headers");
         method2.Parameters.Add(expression);
         expression = new CodeParameterDeclarationExpression(typeof(HttpBrowserCapabilities), "browserCaps");
         method2.Parameters.Add(expression);
         declaration.Members.Add(method2);
         ArrayList list2 = (ArrayList) this._browserOverrides[key];
         CodeStatementCollection stmts = method2.Statements;
         bool flag2 = false;
         foreach (string str4 in list2)
         {
             bd = (BrowserDefinition) base.BrowserTree[str4];
             if ((bd is GatewayDefinition) || bd.IsRefID)
             {
                 base.GenerateSingleProcessCall(bd, method2);
             }
             else
             {
                 if (!flag2)
                 {
                     CodeConditionStatement statement = new CodeConditionStatement {
                         Condition = new CodeVariableReferenceExpression("ignoreApplicationBrowsers")
                     };
                     method2.Statements.Add(statement);
                     stmts = statement.FalseStatements;
                     flag2 = true;
                 }
                 stmts = base.GenerateTrackedSingleProcessCall(stmts, bd, method2);
                 if (this._baseInstance == null)
                 {
                     if (MultiTargetingUtil.IsTargetFramework40OrAbove || (browserCapabilitiesFactoryBaseType.Assembly == BrowserCapabilitiesCompiler.AspBrowserCapsFactoryAssembly))
                     {
                         this._baseInstance = (BrowserCapabilitiesFactoryBase) Activator.CreateInstance(browserCapabilitiesFactoryBaseType);
                     }
                     else
                     {
                         this._baseInstance = new BrowserCapabilitiesFactory35();
                     }
                 }
                 int third = (int) ((Triplet) this._baseInstance.InternalGetBrowserElements()[parentName]).Third;
                 base.AddBrowserToCollectionRecursive(bd, third + 1);
             }
         }
     }
     foreach (DictionaryEntry entry2 in this._defaultBrowserOverrides)
     {
         object obj3 = entry2.Key;
         BrowserDefinition definition3 = (BrowserDefinition) base.DefaultTree[GetFirstItemFromKey(this._defaultBrowserOverrides, obj3)];
         string str5 = definition3.ParentName;
         if (browserCapabilitiesFactoryBaseType.GetMethod("Default" + str5 + "ProcessBrowsers", bindingAttr) == null)
         {
             string str6 = definition3.ParentID;
             if (definition3 != null)
             {
                 throw new ConfigurationErrorsException(System.Web.SR.GetString("DefaultBrowser_parentID_Not_Found", new object[] { str6 }), definition3.XmlNode);
             }
         }
         string str7 = "Default" + str5 + "ProcessBrowsers";
         CodeMemberMethod method3 = new CodeMemberMethod {
             Name = str7,
             ReturnType = new CodeTypeReference(typeof(void)),
             Attributes = MemberAttributes.Family | MemberAttributes.Override
         };
         expression = new CodeParameterDeclarationExpression(typeof(bool), "ignoreApplicationBrowsers");
         method3.Parameters.Add(expression);
         expression = new CodeParameterDeclarationExpression(typeof(NameValueCollection), "headers");
         method3.Parameters.Add(expression);
         expression = new CodeParameterDeclarationExpression(typeof(HttpBrowserCapabilities), "browserCaps");
         method3.Parameters.Add(expression);
         declaration.Members.Add(method3);
         ArrayList list3 = (ArrayList) this._defaultBrowserOverrides[obj3];
         CodeConditionStatement statement2 = new CodeConditionStatement {
             Condition = new CodeVariableReferenceExpression("ignoreApplicationBrowsers")
         };
         method3.Statements.Add(statement2);
         CodeStatementCollection falseStatements = statement2.FalseStatements;
         foreach (string str8 in list3)
         {
             bd = (BrowserDefinition) base.DefaultTree[str8];
             if (bd.IsRefID)
             {
                 base.GenerateSingleProcessCall(bd, method3, "Default");
             }
             else
             {
                 falseStatements = base.GenerateTrackedSingleProcessCall(falseStatements, bd, method3, "Default");
             }
         }
     }
     foreach (DictionaryEntry entry3 in base.BrowserTree)
     {
         bd = entry3.Value as BrowserDefinition;
         base.GenerateProcessMethod(bd, declaration);
     }
     for (int k = 0; k < list.Count; k++)
     {
         foreach (DictionaryEntry entry4 in (BrowserTree) base.CustomTreeList[k])
         {
             bd = entry4.Value as BrowserDefinition;
             base.GenerateProcessMethod(bd, declaration);
         }
     }
     foreach (DictionaryEntry entry5 in base.DefaultTree)
     {
         bd = entry5.Value as BrowserDefinition;
         base.GenerateProcessMethod(bd, declaration, "Default");
     }
     base.GenerateOverrideMatchedHeaders(declaration);
     base.GenerateOverrideBrowserElements(declaration);
     Assembly a = BrowserCapabilitiesCompiler.GetBrowserCapabilitiesFactoryBaseType().Assembly;
     assemblyBuilder.AddAssemblyReference(a, ccu);
     assemblyBuilder.AddCodeCompileUnit(this._buildProvider, ccu);
 }
        //
        // 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);
        }
Esempio n. 4
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);
        }