using System;
using System.ComponentModel;
using System.Configuration;
+using System.Text.RegularExpressions;
+using System.Web.Util;
namespace System.Web.Configuration
{
_properties.Add (verbProp);
}
+ internal HttpHandlerAction ()
+ { }
+
public HttpHandlerAction (string path, string type, string verb)
: this (path, type, verb, true)
{ }
}
protected override ConfigurationPropertyCollection Properties {
+ get { return _properties; }
+ }
+
+#region CompatabilityCode
+ object instance;
+ Type type;
+
+ string cached_verb = null;
+ string[] cached_verbs;
+
+ string cached_path = null;
+ FileMatchingInfo[] cached_files;
+
+ FileMatchingInfo[] SplitPaths ()
+ {
+ string [] paths = Path.Split (',');
+ cached_files = new FileMatchingInfo [paths.Length];
+
+ int i = 0;
+ foreach (string s in paths)
+ cached_files [i++] = new FileMatchingInfo (s);
+
+ return cached_files;
+ }
+
+ string[] SplitVerbs ()
+ {
+ if (Verb == "*")
+ cached_verbs = null;
+ else
+ cached_verbs = Verb.Split (',');
+
+ return cached_verbs;
+ }
+
+ internal string[] Verbs {
+ get {
+ if (cached_verb != Verb) {
+ cached_verbs = SplitVerbs();
+ cached_verb = Verb;
+ }
+
+ return cached_verbs;
+ }
+ }
+
+ FileMatchingInfo[] Paths {
get {
- return _properties;
+ if (cached_path != Path) {
+ cached_files = SplitPaths ();
+ cached_path = Path;
+ }
+
+ return cached_files;
+ }
+ }
+
+ //
+ // Loads the a type by name and verifies that it implements
+ // IHttpHandler or IHttpHandlerFactory
+ //
+ internal static Type LoadType (string type_name)
+ {
+ Type t;
+
+ try {
+ t = System.Type.GetType (type_name, true);
+ } catch (Exception e) {
+ throw new HttpException (String.Format ("Failed to load httpHandler type `{0}'", type_name));
+ }
+
+ if (typeof (IHttpHandler).IsAssignableFrom (t) ||
+ typeof (IHttpHandlerFactory).IsAssignableFrom (t))
+ return t;
+
+ throw new HttpException (String.Format ("Type {0} does not implement IHttpHandler or IHttpHandlerFactory", type_name));
+ }
+
+ internal bool PathMatches (string p)
+ {
+ int slash = p.LastIndexOf ('/');
+ string orig = p;
+ if (slash != -1)
+ p = p.Substring (slash);
+
+ for (int j = Paths.Length; j > 0; ){
+ j--;
+ FileMatchingInfo fm = Paths [j];
+
+ if (fm.MatchExact != null)
+ return fm.MatchExact.Length == p.Length && StrUtils.EndsWith (p, fm.MatchExact);
+
+ if (fm.EndsWith != null)
+ return StrUtils.EndsWith (p, fm.EndsWith);
+
+ if (fm.MatchExpr == "*")
+ return true;
+
+ /* convert to regexp */
+ return fm.RegExp.IsMatch (orig);
+ }
+ return false;
+ }
+
+ // Loads the handler, possibly delay-loaded.
+ internal object GetHandlerInstance ()
+ {
+ IHttpHandler ihh = instance as IHttpHandler;
+
+ if (instance == null || (ihh != null && !ihh.IsReusable)){
+ if (type == null)
+ type = LoadType (Type);
+
+ instance = Activator.CreateInstance (type);
+ }
+
+ return instance;
+ }
+
+ class FileMatchingInfo {
+ public string MatchExact;
+ public string MatchExpr;
+
+ // If set, we can fast-path the patch with string.EndsWith (FMI.EndsWith)
+ public string EndsWith;
+ public Regex RegExp;
+
+ public FileMatchingInfo (string s)
+ {
+ MatchExpr = s;
+
+ if (s[0] == '*' && (s.IndexOf ('*', 1) == -1))
+ EndsWith = s.Substring (1);
+
+ if (s.IndexOf ('*') == -1)
+ MatchExact = "/" + s;
+
+ if (MatchExpr != "*") {
+ string expr = MatchExpr.Replace(".", "\\.").Replace("?", "\\?").Replace("*", ".*");
+ if (expr.Length > 0 && expr [0] =='/')
+ expr = expr.Substring (1);
+
+ expr += "\\z";
+ RegExp = new Regex (expr);
+ }
}
}
+#endregion
+
}
}