|
/*
Used to determine Browser Capabilities by the Browsers UserAgent string.
Copyright (C) 2002-Present Owen Brady (Ocean at xvision.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
using System;
namespace Ocean.Web.HttpCapabilities
{
/// <summary>
/// Summary description for HttpBrowserCapabilities.
/// </summary>
public class Settings
{
/// <summary>
///
/// </summary>
private System.Collections.Specialized.StringDictionary UseVars;
/// <summary>
///
/// </summary>
private System.Collections.Specialized.StringDictionary Items;
/// <summary>
///
/// </summary>
private System.Collections.ArrayList Nodes;
/// <summary>
///
/// </summary>
private System.Web.HttpRequest Request;
/// <summary>
///
/// </summary>
private string UserAgent;
/// <summary>
///
/// </summary>
private string this [string key]
{
get
{
if (key==null || key =="")
{
key ="%{HTTP_USER_AGENT}";
}
if (UseVars.ContainsKey(key.ToLower())==true)
{
return UseVars[key.ToLower()];
}
if (key[0]=='%' && key[1]=='{' && key[key.Length -1]=='}')
{
key = key.Substring(2);
key = key.Substring(0,key.Length -1);
}
if (Items.ContainsKey(key.ToLower())==true)
{
return Items[key.ToLower()];
}
return "";
}
}
/// <summary>
/// Get the current settings from the xml config file
/// </summary>
public static Settings GetSettings()
{
Settings settings = (Settings)System.Configuration.ConfigurationSettings.GetConfig("Ocean.Web/BrowserCaps");
if(settings == null)
{
return Settings.Default;
}
else
{
return settings;
}
}
/// <summary>
/// The default settings. Deflate + normal.
/// </summary>
public static Settings Default
{
get
{
return new Settings();
}
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
public void AddSettings(System.Xml.XmlNode node)
{
Nodes.Add(node);
}
/// <summary>
///
/// </summary>
/// <param name="File"></param>
public void AddSettings(Ocean.Web.HttpCapabilities.EmbededFile File)
{
//------------------------------------------------------
//
//------------------------------------------------------
System.Reflection.Assembly assem = this.GetType().Assembly;
string Resources="Ocean.Web.HttpCapabilities.Resources.";
switch (File)
{
case Ocean.Web.HttpCapabilities.EmbededFile.BrowserCap:
Resources+="xml.BrowserCap";
break;
case Ocean.Web.HttpCapabilities.EmbededFile.MobileCap:
Resources+="xml.Mobile";
break;
case Ocean.Web.HttpCapabilities.EmbededFile.SpidersBots:
Resources+="xml.SpidersBots";
break;
case Ocean.Web.HttpCapabilities.EmbededFile.CodeProject:
Resources+="xml.CodeProject";
break;
}
foreach( string resourceName in assem.GetManifestResourceNames())
{
if (resourceName==Resources)
{
//---------------------------------------------------------------------
//The javascript code which we need has been embeded as a resource in this
//dot.net libary dll. So all we have to do is use the stream method to get
//the raw stream from the dll, so that we can work with it.
//---------------------------------------------------------------------
System.Xml.XmlDocument Doc = new System.Xml.XmlDocument();
Doc.Load(assem.GetManifestResourceStream(resourceName));
this.AddSettings(Doc.DocumentElement);
}
}
}
/// <summary>
///
/// </summary>
private void Reset()
{
UseVars= new System.Collections.Specialized.StringDictionary();
Items = new System.Collections.Specialized.StringDictionary();
}
/// <summary>
///
/// </summary>
public Settings()
{
Reset();
Nodes = new System.Collections.ArrayList();
}
/// <summary>
///
/// </summary>
/// <param name="File"></param>
public Settings(Ocean.Web.HttpCapabilities.EmbededFile File):this()
{
this.AddSettings(File);
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
public Settings(System.Xml.XmlNode node):this()
{
this.AddSettings(node);
}
/// <summary>
///
/// </summary>
/// <param name="useragent"></param>
/// <returns></returns>
public Result Process(string useragent)
{
System.Diagnostics.Trace.WriteLine("Process");
Reset();
UserAgent = useragent;
ProcessBase();
return new Ocean.Web.HttpCapabilities.Result(Items);
}
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public Result Process(System.Web.HttpRequest request)
{
Reset();
Request =request;
UserAgent =request["HTTP_USER_AGENT"];
ProcessBase();
return new Ocean.Web.HttpCapabilities.Result(Items);
}
/// <summary>
///
/// </summary>
internal void ProcessBase()
{
System.Diagnostics.Trace.WriteLine("ProcessBase");
foreach (System.Xml.XmlNode node in Nodes)
{
ProcessNode(node);
}
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
internal void ProcessNode(System.Xml.XmlNode node)
{
System.Diagnostics.Trace.WriteLine("ProcessNode");
if (node==null || node.ChildNodes ==null)
{
return;
}
foreach (System.Xml.XmlNode E in node.ChildNodes)
{
switch (E.Name.ToLower())
{
case "result":
//do nothing with this currently
break;
case "use":
ProcessUse(E);
break;
case "#text":
ProcessItems(E);
break;
case "filter":
if( E.HasChildNodes ==true)
{
Processfilter(E);
}
break;
}
}
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
internal bool ProcessCase(System.Xml.XmlNode node)
{
return ProcessCase(node,null);
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
/// <param name="RegMatch"></param>
/// <returns></returns>
internal bool ProcessCase(System.Xml.XmlNode node,Ocean.Web.HttpCapabilities.CaseFilter RegMatch)
{
System.Diagnostics.Trace.WriteLine("ProcessCase");
string matchvalue ="";
string matchwith ="";
if (node.Attributes["match"]!=null)
{
matchvalue = node.Attributes["match"].Value;
}
if (node.Attributes["with"]!=null)
{
matchwith = node.Attributes["with"].Value;
if (matchwith.Length >0 && matchwith[0]=='$' && RegMatch.CountGroups >0)
{
matchwith =RegMatch.Result(matchwith);
}
else if (matchwith.Length >0 && matchwith[0]=='%')
{
matchwith = this[matchwith];
}
}
else
{
matchwith = this[matchwith];
}
Ocean.Web.HttpCapabilities.CaseFilter LocalMatch = new Ocean.Web.HttpCapabilities.CaseFilter(matchvalue,matchwith);
if (LocalMatch.Success ==false)
{
return false;
}
else
{
System.Diagnostics.Trace.WriteLine(string.Format("value:{0}\twith:{1}",matchvalue,matchwith));
}
foreach (System.Xml.XmlNode E in node.ChildNodes)
{
switch (E.Name.ToLower())
{
case "#text":
string raw = E.Value;
if (LocalMatch.CountGroups >0)
{
raw = LocalMatch.Result(raw);
}
if (RegMatch!=null && RegMatch.CountGroups >0)
{
raw = RegMatch.Result(raw);
}
ProcessItems(raw);
break;
case "case":
if( E.HasChildNodes ==true)
{
bool CaseValue=false;
if (LocalMatch.CountGroups >1)
{
CaseValue = ProcessCase(E,LocalMatch);
}
else
{
CaseValue = ProcessCase(E,RegMatch);
}
if (CaseValue==true)
{
return true;
}
}
break;
case "filter":
if( E.HasChildNodes ==true)
{
if (LocalMatch.CountGroups >1)
{
Processfilter(E,LocalMatch);
}
else
{
Processfilter(E,RegMatch);
}
}
break;
}
}
return true;
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
internal void Processfilter(System.Xml.XmlNode node)
{
Processfilter(node,null);
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
/// <param name="RegMatch"></param>
internal void Processfilter(System.Xml.XmlNode node,Ocean.Web.HttpCapabilities.CaseFilter RegMatch)
{
System.Diagnostics.Trace.WriteLine("Processfilter");
string matchvalue ="";
string matchwith ="";
if (node.Attributes["match"]!=null)
{
matchvalue = node.Attributes["match"].Value;
}
if (node.Attributes["with"]!=null)
{
matchwith = node.Attributes["with"].Value;
if (matchwith.Length >0 && matchwith[0]=='$' && RegMatch.CountGroups >0)
{
matchwith =RegMatch.Result(matchwith);
}
else if (matchwith.Length >0 && matchwith[0]=='%')
{
matchwith = this[matchwith];
}
}
else
{
matchwith = this[matchwith];
}
if (matchwith==null)
{
matchwith =string.Empty;
}
Ocean.Web.HttpCapabilities.CaseFilter LocalMatch = new Ocean.Web.HttpCapabilities.CaseFilter(matchvalue,matchwith);
if (LocalMatch.Success ==false)
{
return ;
}
foreach (System.Xml.XmlNode E in node.ChildNodes)
{
switch (E.Name.ToLower())
{
case "#text":
string raw = E.Value;
if (LocalMatch.CountGroups >0)
{
raw = LocalMatch.Result(raw);
}
if (RegMatch!=null && RegMatch.CountGroups >0)
{
raw = RegMatch.Result(raw);
}
ProcessItems(raw);
break;
case "case":
if( E.HasChildNodes ==true)
{
bool CaseValue=false;
if (LocalMatch.CountGroups >1)
{
CaseValue = ProcessCase(E,LocalMatch);
}
else
{
CaseValue = ProcessCase(E,RegMatch);
}
if (CaseValue==true)
{
return;
}
}
break;
case "filter":
if( E.HasChildNodes ==true)
{
if (LocalMatch.CountGroups >1)
{
Processfilter(E,LocalMatch);
}
else
{
Processfilter(E,RegMatch);
}
}
break;
}
}
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
internal void ProcessUse(System.Xml.XmlNode node)
{
System.Diagnostics.Trace.WriteLine("ProcessUse");
string matchvar = node.Attributes["var"].Value;
string matchas = null;
string HeaderResult ="";
if (node.Attributes["as"]!=null)
{
if (node.Attributes["as"].Value!=null)
{
matchas = node.Attributes["as"].Value.Trim();
}
else
{
matchas =string.Empty;
}
}
else
{
matchas="HTTP_USER_AGENT";
}
System.Diagnostics.Trace.WriteLine("matchas:{0}",matchas);
if (matchvar!=null)
{
if (matchas!=string.Empty)
{
matchas ="%{" + matchas.Trim() +"}";
if (matchas=="%{HTTP_USER_AGENT}")
{
HeaderResult = UserAgent;
}
else if (Request!=null && Request[matchvar]!=null && Request[matchvar]!=string.Empty)
{
HeaderResult = Request[matchvar];
}
else
{
//no header that matches it so we have to put something there
//so I put in an empty string.
HeaderResult =string.Empty;
}
if (UseVars.ContainsKey(matchas)==false)
{
UseVars.Add(matchas,HeaderResult);
}
else
{
UseVars[matchas] = HeaderResult;
}
}
}
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
internal void ProcessItems(System.Xml.XmlNode node)
{
ProcessItems(node.Value);
}
/// <summary>
///
/// </summary>
/// <param name="raw"></param>
internal void ProcessItems(string raw)
{
System.Diagnostics.Trace.WriteLine("ProcessItems");
//--------------------------------------------------
//removing all the tabs out of the raw string
//--------------------------------------------------
while (raw.IndexOf("\t")>-1)
{
raw = raw.Replace("\t","");
}
//--------------------------------------------------
//removing all the line feeds out of the raw string
//--------------------------------------------------
while (raw.IndexOf("\n")>-1)
{
raw = raw.Replace("\n","");
}
//--------------------------------------------------
//removing all the double control breaks out of the
//raw string
//--------------------------------------------------
while (raw.IndexOf("\r\r")>-1)
{
raw = raw.Replace("\r\r","\r");
}
//--------------------------------------------------
//removing all double blank spaces from the raw string
//--------------------------------------------------
while (raw.IndexOf(" ")>-1)
{
raw = raw.Replace(" "," ");
}
System.Text.RegularExpressions.Match M;
M = System.Text.RegularExpressions.Regex.Match(raw,@"%{\w*}");
while (M.Success==true)
{
for (int a=0;a<=M.Captures.Count -1;a++)
{
string s= M.Captures[a].Value;
raw =raw.Replace(s,this[s]);
}
M = System.Text.RegularExpressions.Regex.Match(raw,@"%{\w*}");
}
//--------------------------------------------------
//Split the Array
//--------------------------------------------------
string[] itemsArray = System.Text.RegularExpressions.Regex.Split(raw,"\r");
for (int i=0; i<= itemsArray.Length -1;i++)
{
itemsArray[i] = itemsArray[i].Trim();
if(itemsArray[i]!="")
{
//--------------------------------------------------
//only have to act if there is equal sign in the string
//--------------------------------------------------
if ( itemsArray[i].IndexOf("=")>-1)
{
string[] a = itemsArray[i].Split('=');
a[1] = a[1].Trim();
//--------------------------------------------------
//always use lower case keys
//--------------------------------------------------
a[0] = a[0].Trim().ToLower();
//--------------------------------------------------
//just remove the quotes and move on
//--------------------------------------------------
while (a[1].IndexOf("\"")>-1)
{
a[1] = a[1].Replace("\"","");
}
//--------------------------------------------------
//just making sure the varables are cleared out if they
//didn't take
//--------------------------------------------------
if (a[1].Length >2)
{
if (a[1].Substring(0,2) =="${")
{
a[1]=string.Empty;
}
}
//--------------------------------------------------
//this assigns the key/value pair to the string dictionary
//--------------------------------------------------
if (a[1]!=string.Empty)
{
if (Items.ContainsKey(a[0])==true)
{
Items[a[0]] = a[1];
}
else
{
Items.Add(a[0],a[1]);
}
}
}
}
}
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Chris Maunder is the co-founder of
CodeProject and
ContentLab.com, and has been a prominent figure in the software development community for nearly 30 years. Hailing from Australia, Chris has a background in Mathematics, Astrophysics, Environmental Engineering and Defence Research. His programming endeavours span everything from FORTRAN on Super Computers, C++/MFC on Windows, through to to high-load .NET web applications and Python AI applications on everything from macOS to a Raspberry Pi. Chris is a full-stack developer who is as comfortable with SQL as he is with CSS.
In the late 1990s, he and his business partner David Cunningham recognized the need for a platform that would facilitate knowledge-sharing among developers, leading to the establishment of CodeProject.com in 1999. Chris's expertise in programming and his passion for fostering a collaborative environment have played a pivotal role in the success of CodeProject.com. Over the years, the website has grown into a vibrant community where programmers worldwide can connect, exchange ideas, and find solutions to coding challenges. Chris is a prolific contributor to the developer community through his articles and tutorials, and his latest passion project,
CodeProject.AI.
In addition to his work with CodeProject.com, Chris co-founded ContentLab and DeveloperMedia, two projects focussed on helping companies make their Software Projects a success. Chris's roles included Product Development, Content Creation, Client Satisfaction and Systems Automation.