// // System.Web.CapabilitiesLoader // // Loads data from browscap.ini file provided by Gary J. Keith from // http://www.GaryKeith.com/browsers. Please don't abuse the // site when updating browscap.ini file. Use the update-browscap.exe tool. // // Authors: // Gonzalo Paniagua Javier (gonzalo@ximian.com) // // (c) 2003 Novell, Inc. (http://www.novell.com) // using System; using System.Collections; using System.Collections.Specialized; using System.Globalization; using System.IO; using System.Text.RegularExpressions; using System.Web.Configuration; namespace System.Web { class BrowserData { static char [] wildchars = new char [] {'*', '?'}; BrowserData parent; string text; string pattern; Regex regex; ListDictionary data; public BrowserData (string pattern) { int norx = pattern.IndexOfAny (wildchars); if (norx == -1) { text = pattern; } else { this.pattern = pattern.Substring (norx); text = pattern.Substring (0, norx); if (text.Length == 0) text = null; this.pattern = this.pattern.Replace (".", "\\."); this.pattern = this.pattern.Replace ("(", "\\("); this.pattern = this.pattern.Replace (")", "\\)"); this.pattern = this.pattern.Replace ("[", "\\["); this.pattern = this.pattern.Replace ("]", "\\]"); this.pattern = this.pattern.Replace ("?", "."); this.pattern = this.pattern.Replace ("*", ".*"); } } public BrowserData Parent { get { return parent; } set { parent = value; } } public void Add (string key, string value) { lock (this) { if (data == null) data = new ListDictionary (); data.Add (key, value); } } public Hashtable GetProperties (Hashtable tbl) { if (parent != null) parent.GetProperties (tbl); foreach (string key in data.Keys) tbl [key] = data [key]; return tbl; } public string GetParentName () { return (string) data ["parent"]; } public string GetAlternateBrowser () { return (pattern == null) ? text : null; } public string GetBrowser () { if (pattern == null) return text; return (string) data ["browser"]; } public bool IsMatch (string expression) { if (expression == null || expression.Length == 0) return false; if (text != null) { if (text [0] != expression [0] || String.Compare (text, 1, expression, 1, text.Length - 1, false, CultureInfo.InvariantCulture) != 0) { return false; } expression = expression.Substring (text.Length); } lock (this) { if (pattern == null) return expression.Length == 0; if (regex == null) regex = new Regex (pattern); } return regex.Match (expression).Success; } } class CapabilitiesLoader : MarshalByRefObject { static bool loaded; static ICollection alldata; static Hashtable defaultCaps; private CapabilitiesLoader () {} public static Hashtable GetCapabilities (string userAgent) { Init (); if (userAgent != null) userAgent = userAgent.Trim (); if (alldata == null || userAgent == null || userAgent == "") return DefaultCapabilities; foreach (BrowserData bd in alldata) { if (bd.IsMatch (userAgent)) { return bd.GetProperties (new Hashtable ()); } } return DefaultCapabilities; } static void Init () { lock (typeof (CapabilitiesLoader)) { if (loaded) return; string path = Path.GetDirectoryName (WebConfigurationSettings.MachineConfigPath); path = Path.Combine (path, "browscap.ini"); try { LoadFile (path); } catch (Exception e) { } loaded = true; } } static void LoadFile (string filename) { if (!File.Exists (filename)) return; TextReader input = new StreamReader (File.OpenRead (filename)); string str; Hashtable allhash = new Hashtable (); int aux = 0; while ((str = input.ReadLine ()) != null) { if (str.Length == 0 || str [0] == ';') continue; string userAgent = str.Substring (1, str.Length - 2); BrowserData data = new BrowserData (userAgent); ReadCapabilities (input, data); /* Ignore default browser and file version information */ if (userAgent == "*" || userAgent == "GJK_Browscap_Version") continue; string key = data.GetBrowser (); if (key == null || allhash.ContainsKey (key)) { allhash.Add (aux++, data); } else { allhash.Add (key, data); } } alldata = allhash.Values; foreach (BrowserData data in alldata) { if (data.Parent != null) continue; string pname = data.GetParentName (); if (pname != null) data.Parent = (BrowserData) allhash [pname]; } } static char [] eq = new char []{'='}; static void ReadCapabilities (TextReader input, BrowserData data) { string str; while ((str = input.ReadLine ()) != null && str.Length != 0) { string [] keyvalue = str.Split (eq, 2); data.Add (keyvalue [0], keyvalue [1]); } } static Hashtable DefaultCapabilities { get { lock (typeof (CapabilitiesLoader)) { if (defaultCaps != null) return defaultCaps; defaultCaps = new Hashtable (); defaultCaps.Add ("frames", "True"); defaultCaps.Add ("tables", "True"); return defaultCaps; } } } } }