Visual studio upgrade did not work well.
[mono.git] / mcs / class / System.Web / System.Web.Configuration_2.0 / HttpHandlerAction.cs
1 //
2 // System.Web.Configuration.HttpHandlerAction
3 //
4 // Authors:
5 //      Chris Toshok (toshok@ximian.com)
6 //      Daniel Nauck    (dna(at)mono-project(dot)de)
7 //
8 // (C) 2005 Novell, Inc (http://www.novell.com)
9 // (C) 2008 Daniel Nauck
10 //
11
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 #if NET_2_0
34
35 using System;
36 using System.Collections;
37 using System.Collections.Generic;
38 using System.ComponentModel;
39 using System.Configuration;
40 using System.Reflection;
41 using System.Text.RegularExpressions;
42 using System.Web;
43 using System.Web.Util;
44
45 namespace System.Web.Configuration
46 {
47         public sealed class HttpHandlerAction: ConfigurationElement
48         {
49                 static ConfigurationPropertyCollection _properties;
50                 static ConfigurationProperty pathProp;
51                 static ConfigurationProperty typeProp;
52                 static ConfigurationProperty validateProp;
53                 static ConfigurationProperty verbProp;
54
55                 static HttpHandlerAction ()
56                 {
57                         pathProp = new ConfigurationProperty ("path", typeof (string), null,
58                                                               TypeDescriptor.GetConverter (typeof (string)),
59                                                               PropertyHelper.NonEmptyStringValidator,
60                                                               ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey);
61                         typeProp = new ConfigurationProperty ("type", typeof (string), null,
62                                                               TypeDescriptor.GetConverter (typeof (string)),
63                                                               PropertyHelper.NonEmptyStringValidator,
64                                                               ConfigurationPropertyOptions.IsRequired);
65                         validateProp = new ConfigurationProperty ("validate", typeof (bool), true);
66                         verbProp = new ConfigurationProperty ("verb", typeof (string), null,
67                                                               TypeDescriptor.GetConverter (typeof (string)),
68                                                               PropertyHelper.NonEmptyStringValidator,
69                                                               ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey);
70
71                         _properties = new ConfigurationPropertyCollection ();
72                         _properties.Add (pathProp);
73                         _properties.Add (typeProp);
74                         _properties.Add (validateProp);
75                         _properties.Add (verbProp);
76                 }
77
78                 internal HttpHandlerAction ()
79                 { }
80
81                 public HttpHandlerAction (string path, string type, string verb)
82                         : this (path, type, verb, true)
83                 { }
84
85                 public HttpHandlerAction (string path, string type, string verb, bool validate)
86                 {
87                         Path = path;
88                         Type = type;
89                         Verb = verb;
90                         Validate = validate;
91                 }
92
93                 [ConfigurationProperty ("path", Options = ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey)]
94                 // LAMESPEC: MS lists no validator here but provides one in Properties.
95                 public string Path {
96                         get { return (string) base[pathProp]; }
97                         set { base[pathProp] = value; }
98                 }
99
100                 [ConfigurationProperty ("type", Options = ConfigurationPropertyOptions.IsRequired)]
101                 // LAMESPEC: MS lists no validator here but provides one in Properties.
102                 public string Type {
103                         get { return (string) base[typeProp]; }
104                         set { base[typeProp] = value; }
105                 }
106
107                 [ConfigurationProperty ("validate", DefaultValue = true)]
108                 public bool Validate {
109                         get { return (bool) base[validateProp]; }
110                         set { base[validateProp] = value; }
111                 }
112
113                 [ConfigurationProperty ("verb", Options = ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey)]
114                 // LAMESPEC: MS lists no validator here but provides one in Properties.
115                 public string Verb {
116                         get { return (string) base[verbProp]; }
117                         set { base[verbProp] = value; }
118                 }
119
120                 protected override ConfigurationPropertyCollection Properties {
121                         get { return _properties; }
122                 }
123
124 #region CompatabilityCode
125                 object instance;
126                 Type type;
127
128                 string cached_verb = null;
129                 string[] cached_verbs;
130                 Dictionary<string, bool> cachedMatches = new Dictionary<string, bool> ();
131                 Object pathMatchesLock = new Object ();
132
133                 string[] SplitVerbs ()
134                 {
135                         if (Verb == "*")
136                                 cached_verbs = null;
137                         else
138                                 cached_verbs = Verb.Split (',');
139
140                         return cached_verbs;
141                 }
142
143                 internal string[] Verbs {
144                         get {
145                                 if (cached_verb != Verb) {
146                                         cached_verbs = SplitVerbs();
147                                         cached_verb = Verb;
148                                 }
149
150                                 return cached_verbs;
151                         }
152                 }
153
154                 //
155                 // Loads the a type by name and verifies that it implements
156                 // IHttpHandler or IHttpHandlerFactory
157                 //
158                 internal static Type LoadType (string type_name)
159                 {
160                         Type t = null;
161                         
162                         t = HttpApplication.LoadType (type_name, false);
163
164                         if (t == null)
165                                 throw new HttpException (String.Format ("Failed to load httpHandler type `{0}'", type_name));
166
167                         if (typeof (IHttpHandler).IsAssignableFrom (t) ||
168                             typeof (IHttpHandlerFactory).IsAssignableFrom (t))
169                                 return t;
170                         
171                         throw new HttpException (String.Format ("Type {0} does not implement IHttpHandler or IHttpHandlerFactory", type_name));
172                 }
173
174                 internal bool PathMatches (string pathToMatch)
175                 {
176                         if (cachedMatches.ContainsKey (pathToMatch))
177                                 return cachedMatches [pathToMatch];
178
179                         lock (pathMatchesLock)
180                         {
181                                 if (cachedMatches.ContainsKey (pathToMatch))
182                                         return cachedMatches [pathToMatch];
183
184                                 bool result = false;
185                                 string[] handlerPaths = Path.Split (',');
186                                 int slash = pathToMatch.LastIndexOf ('/');
187                                 string origPathToMatch = pathToMatch;
188                                 if (slash != -1)
189                                         pathToMatch = pathToMatch.Substring (slash);
190
191                                 foreach (string handlerPath in handlerPaths)
192                                 {
193                                         if (handlerPath == "*")
194                                         {
195                                                 result = true;
196                                                 break;
197                                         }
198
199                                         string matchExact = null;
200                                         string endsWith = null;
201                                         Regex regEx = null;
202
203                                         if (handlerPath.Length > 0)
204                                         {
205                                                 if (handlerPath [0] == '*' && (handlerPath.IndexOf ('*', 1) == -1))
206                                                         endsWith = handlerPath.Substring (1);
207
208                                                 if (handlerPath.IndexOf ('*') == -1)
209                                                         if (handlerPath [0] != '/')
210                                                         {
211                                                                 HttpContext ctx = HttpContext.Current;
212                                                                 HttpRequest req = ctx != null ? ctx.Request : null;
213                                                                 string vpath = req != null ? req.BaseVirtualDir : HttpRuntime.AppDomainAppVirtualPath;
214
215                                                                 if (vpath == "/")
216                                                                         vpath = String.Empty;
217
218                                                                 matchExact = String.Concat (vpath, "/", handlerPath);
219                                                         }
220                                         }
221
222                                         if (matchExact != null)
223                                         {
224                                                 result = matchExact.Length == origPathToMatch.Length && StrUtils.EndsWith (origPathToMatch, matchExact, true);
225                                                 if (result == true)
226                                                         break;
227                                                 else
228                                                         continue;
229                                         }
230                                         else if (endsWith != null)
231                                         {
232                                                 result = StrUtils.EndsWith (pathToMatch, endsWith, true);
233                                                 if (result == true)
234                                                         break;
235                                                 else
236                                                         continue;
237                                         }
238
239                                         if (handlerPath != "*")
240                                         {
241                                                 string expr = handlerPath.Replace (".", "\\.").Replace ("?", "\\?").Replace ("*", ".*");
242                                                 if (expr.Length > 0 && expr [0] == '/')
243                                                         expr = expr.Substring (1);
244
245                                                 expr += "\\z";
246                                                 regEx = new Regex (expr, RegexOptions.IgnoreCase);
247
248                                                 if (regEx.IsMatch (origPathToMatch))
249                                                 {
250                                                         result = true;
251                                                         break;
252                                                 }
253                                         }
254                                 }
255
256                                 if (!cachedMatches.ContainsKey (origPathToMatch))
257                                         cachedMatches.Add (origPathToMatch, result);
258
259                                 return result;
260                         }
261                 }
262
263                 // Loads the handler, possibly delay-loaded.
264                 internal object GetHandlerInstance ()
265                 {
266                         IHttpHandler ihh = instance as IHttpHandler;
267                         
268                         if (instance == null || (ihh != null && !ihh.IsReusable)){
269                                 if (type == null)
270                                         type = LoadType (Type);
271
272                                 instance = Activator.CreateInstance (type);
273                         } 
274                         
275                         return instance;
276                 }
277 #endregion
278
279         }
280
281 }
282
283 #endif