New test.
[mono.git] / mcs / class / System.Web / System.Web.Configuration_2.0 / WebConfigurationHost.cs
1 //
2 // System.Web.Configuration.WebConfigurationHost.cs
3 //
4 // Authors:
5 //  Lluis Sanchez Gual (lluis@novell.com)
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining
8 // a copy of this software and associated documentation files (the
9 // "Software"), to deal in the Software without restriction, including
10 // without limitation the rights to use, copy, modify, merge, publish,
11 // distribute, sublicense, and/or sell copies of the Software, and to
12 // permit persons to whom the Software is furnished to do so, subject to
13 // the following conditions:
14 // 
15 // The above copyright notice and this permission notice shall be
16 // included in all copies or substantial portions of the Software.
17 // 
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 //
26 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
27 //
28
29 #if NET_2_0
30
31 using System;
32 using System.IO;
33 using System.Security;
34 using System.Configuration;
35 using System.Configuration.Internal;
36 using System.Web.Util;
37 using System.Reflection;
38
39 /*
40  * this class needs to be rewritten to support usage of the
41  * IRemoteWebConfigurationHostServer interface.  Once that's done, we
42  * need an implementation of that interface that talks (through a web
43  * service?) to a remote site..
44  *
45  * for now, though, just implement it as we do
46  * System.Configuration.InternalConfigurationHost, i.e. the local
47  * case.
48  */
49 namespace System.Web.Configuration
50 {
51         class WebConfigurationHost: IInternalConfigHost
52         {
53                 WebConfigurationFileMap map;
54                 const string MachinePath = ":machine:";
55                 const string MachineWebPath = ":web:";
56                 
57                 public virtual object CreateConfigurationContext (string configPath, string locationSubPath)
58                 {
59                         return new WebContext (WebApplicationLevel.AtApplication /* XXX */,
60                                                "" /* site XXX */,
61                                                "" /* application path XXX */,
62                                                configPath,
63                                                locationSubPath);
64                 }
65                 
66                 public virtual object CreateDeprecatedConfigContext (string configPath)
67                 {
68                         throw new NotImplementedException ();
69                 }
70                 
71                 public virtual string DecryptSection (string encryptedXml, ProtectedConfigurationProvider protectionProvider, ProtectedConfigurationSection protectedSection)
72                 {
73                         throw new NotImplementedException ();
74                 }
75                 
76                 public virtual void DeleteStream (string streamName)
77                 {
78                         File.Delete (streamName);
79                 }
80                 
81                 public virtual string EncryptSection (string encryptedXml, ProtectedConfigurationProvider protectionProvider, ProtectedConfigurationSection protectedSection)
82                 {
83                         throw new NotImplementedException ();
84                 }
85                 
86                 public virtual string GetConfigPathFromLocationSubPath (string configPath, string locatinSubPath)
87                 {
88                         return configPath + "/" + locatinSubPath;
89                 }
90
91                 private static string privateBinPath;
92
93                 private static string PrivateBinPath {
94                         get {
95                                 if (privateBinPath != null)
96                                         return privateBinPath;
97                                 
98                                 AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
99                                 privateBinPath = Path.Combine(setup.ApplicationBase, setup.PrivateBinPath);
100                                 return privateBinPath;
101                         }
102                 }
103                 
104                 private Type LoadType(string typeName)
105                 {
106                         Type type = Type.GetType (typeName);
107                         if (type != null)
108                                 return type;
109
110                         if (!Directory.Exists (PrivateBinPath))
111                                 return null;
112                         
113                         string[] binDlls = Directory.GetFiles(PrivateBinPath, "*.dll");
114                         foreach (string s in binDlls) {
115                                 Assembly binA = Assembly.LoadFrom (s);
116                                 type = binA.GetType (typeName);
117                                 if (type == null)
118                                         continue;
119                                 
120                                 return type;
121                         }
122                         
123                         return null;
124                 }
125                 
126                 public virtual Type GetConfigType (string typeName, bool throwOnError)
127                 {
128                         Type type = LoadType(typeName);
129                         if (type == null && throwOnError)
130                                 throw new ConfigurationErrorsException ("Type not found: '" + typeName + "'");
131                         return type;
132                 }
133                 
134                 public virtual string GetConfigTypeName (Type t)
135                 {
136                         return t.AssemblyQualifiedName;
137                 }
138                 
139                 public virtual void GetRestrictedPermissions (IInternalConfigRecord configRecord, out PermissionSet permissionSet, out bool isHostReady)
140                 {
141                         throw new NotImplementedException ();
142                 }
143                 
144                 public virtual string GetStreamName (string configPath)
145                 {
146                         if (configPath == MachinePath) {
147                                 if (map == null)
148                                         return System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile;
149                                 else
150                                         return map.MachineConfigFilename;
151                         } else if (configPath == MachineWebPath) {
152                                 string mdir;
153
154                                 if (map == null)
155 #if TARGET_JVM
156                                         return "/web.config";
157 #else
158                                         mdir = Path.GetDirectoryName (System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile);
159 #endif
160                                 else
161                                         mdir = Path.GetDirectoryName (map.MachineConfigFilename);
162
163                                 return GetWebConfigFileName (mdir);
164                         }
165                         
166                         string dir = MapPath (configPath);
167                         return GetWebConfigFileName (dir);
168                 }
169                 
170                 public virtual string GetStreamNameForConfigSource (string streamName, string configSource)
171                 {
172                         throw new NotImplementedException ();
173                 }
174                 
175                 public virtual object GetStreamVersion (string streamName)
176                 {
177                         throw new NotImplementedException ();
178                 }
179                 
180                 public virtual IDisposable Impersonate ()
181                 {
182                         throw new NotImplementedException ();
183                 }
184                 
185                 public virtual void Init (IInternalConfigRoot root, params object[] hostInitParams)
186                 {
187                 }
188                 
189                 public virtual void InitForConfiguration (ref string locationSubPath, out string configPath, out string locationConfigPath, IInternalConfigRoot root, params object[] hostInitConfigurationParams)
190                 {
191                         string fullPath = (string) hostInitConfigurationParams [1];
192                         
193                         map = (WebConfigurationFileMap) hostInitConfigurationParams [0];
194                         
195                         if (locationSubPath == MachineWebPath) {
196                                 locationSubPath = MachinePath;
197                                 configPath = MachineWebPath;
198                                 locationConfigPath = null;
199                         }
200                         else if (locationSubPath == MachinePath) {
201                                 locationSubPath = null;
202                                 configPath = MachinePath;
203                                 locationConfigPath = null;
204                         }
205                         else {
206                                 
207                                 int i;
208                                 if (locationSubPath == null)
209                                         configPath = fullPath;
210                                 else
211                                         configPath = locationSubPath;
212
213                                 if (configPath == HttpRuntime.AppDomainAppVirtualPath
214                                     || configPath == "/")
215                                         i = -1;
216                                 else
217                                         i = configPath.LastIndexOf ("/");
218                                 
219                                 if (i != -1) {
220                                         locationConfigPath = configPath.Substring (i+1);
221                                         
222                                         if (i == 0)
223                                                 locationSubPath = "/";
224                                         else
225                                                 locationSubPath = fullPath.Substring (0, i);
226                                 } else {
227                                         locationSubPath = MachineWebPath;
228                                         locationConfigPath = null;
229                                 }
230                         }
231                 }
232                 
233                 public string MapPath (string virtualPath)
234                 {
235                         if (map != null)
236                                 return MapPathFromMapper (virtualPath);
237                         else if (HttpContext.Current != null
238                                  && HttpContext.Current.Request != null)
239                                 return HttpContext.Current.Request.MapPath (virtualPath);
240                         else if (HttpRuntime.AppDomainAppVirtualPath != null && virtualPath.StartsWith (HttpRuntime.AppDomainAppVirtualPath)) {
241                                 if (virtualPath == HttpRuntime.AppDomainAppVirtualPath)
242                                         return HttpRuntime.AppDomainAppPath;
243                                 return UrlUtils.Combine (HttpRuntime.AppDomainAppPath, virtualPath.Substring (HttpRuntime.AppDomainAppVirtualPath.Length));
244                         }
245                         else
246                                 return virtualPath;
247                 }
248                 
249                 public string NormalizeVirtualPath (string virtualPath)
250                 {
251                         if (virtualPath == null || virtualPath.Length == 0)
252                                 virtualPath = ".";
253                         else
254                                 virtualPath = virtualPath.Trim ();
255
256                         if (virtualPath [0] == '~' && virtualPath.Length > 2 && virtualPath [1] == '/')
257                                 virtualPath = virtualPath.Substring (1);
258                                 
259                         if (System.IO.Path.DirectorySeparatorChar != '/')
260                                 virtualPath = virtualPath.Replace (System.IO.Path.DirectorySeparatorChar, '/');
261
262                         if (UrlUtils.IsRooted (virtualPath)) {
263                                 virtualPath = UrlUtils.Canonic (virtualPath);
264                         } else {
265                                 if (map.VirtualDirectories.Count > 0) {
266                                         string root = map.VirtualDirectories [0].VirtualDirectory;
267                                         virtualPath = UrlUtils.Combine (root, virtualPath);
268                                         virtualPath = UrlUtils.Canonic (virtualPath);
269                                 }
270                         }
271                         return virtualPath;
272                 }
273
274                 public string MapPathFromMapper (string virtualPath)
275                 {
276                         string path = NormalizeVirtualPath (virtualPath);
277                         
278                         foreach (VirtualDirectoryMapping mapping in map.VirtualDirectories) {
279                                 if (path.StartsWith (mapping.VirtualDirectory)) {
280                                         int i = mapping.VirtualDirectory.Length;
281                                         if (path.Length == i) {
282                                                 return mapping.PhysicalDirectory;
283                                         }
284                                         else if (path [i] == '/') {
285                                                 string pathPart = path.Substring (i + 1).Replace ('/', Path.DirectorySeparatorChar);
286                                                 return Path.Combine (mapping.PhysicalDirectory, pathPart);
287                                         }
288                                 }
289                         }
290                         throw new HttpException ("Invalid virtual directory: " + virtualPath);
291                 }
292
293                 string GetWebConfigFileName (string dir)
294                 {
295                         string[] filenames = new string[] {"Web.Config", "Web.config", "web.config" };
296
297                         foreach (string fn in filenames) {
298                                 string file = Path.Combine (dir, fn);
299                                 if (File.Exists (file))
300                                         return file;
301                         }
302
303                         return null;
304                 }
305                 
306                 public virtual bool IsAboveApplication (string configPath)
307                 {
308                         throw new NotImplementedException ();
309                 }
310                 
311                 public virtual bool IsConfigRecordRequired (string configPath)
312                 {
313                         throw new NotImplementedException ();
314                 }
315                 
316                 public virtual bool IsDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition)
317                 {
318                         switch (allowDefinition) {
319                                 case ConfigurationAllowDefinition.MachineOnly:
320                                         return configPath == MachinePath || configPath == MachineWebPath;
321                                 case ConfigurationAllowDefinition.MachineToWebRoot:
322                                 case ConfigurationAllowDefinition.MachineToApplication:
323                                         return configPath == MachinePath || configPath == MachineWebPath || configPath == "/";
324                                 default:
325                                         return true;
326                         }
327                 }
328                 
329                 public virtual bool IsFile (string streamName)
330                 {
331                         throw new NotImplementedException ();
332                 }
333                 
334                 public virtual bool IsLocationApplicable (string configPath)
335                 {
336                         throw new NotImplementedException ();
337                 }
338                 
339                 public virtual Stream OpenStreamForRead (string streamName)
340                 {
341                         if (!File.Exists (streamName)) {
342 #if TARGET_J2EE
343                                 if (streamName != null && (streamName.EndsWith ("machine.config") || streamName.EndsWith ("web.config"))) {
344                                         if (streamName.StartsWith ("/"))
345                                                 streamName = streamName.Substring (1);
346                                         java.lang.ClassLoader cl = (java.lang.ClassLoader) AppDomain.CurrentDomain.GetData ("GH_ContextClassLoader");
347                                         if (cl != null) {
348                                                 java.io.InputStream inputStream = cl.getResourceAsStream (streamName);
349                                                 return (Stream) vmw.common.IOUtils.getStream (inputStream);
350                                         }
351                                 }
352 #endif
353                                 throw new ConfigurationException ("File '" + streamName + "' not found");
354                         }
355                                 
356                         return new FileStream (streamName, FileMode.Open, FileAccess.Read);
357                 }
358
359                 [MonoTODO ("Not implemented")]
360                 public virtual Stream OpenStreamForRead (string streamName, bool assertPermissions)
361                 {
362                         throw new NotImplementedException ();
363                 }
364
365                 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext)
366                 {
367                         return new FileStream (streamName, FileMode.Create, FileAccess.Write);
368                 }
369
370                 [MonoTODO ("Not implemented")]
371                 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext, bool assertPermissions)
372                 {
373                         throw new NotImplementedException ();
374                 }
375                 
376                 public virtual bool PrefetchAll (string configPath, string streamName)
377                 {
378                         throw new NotImplementedException ();
379                 }
380                 
381                 public virtual bool PrefetchSection (string sectionGroupName, string sectionName)
382                 {
383                         throw new NotImplementedException ();
384                 }
385
386                 [MonoTODO ("Not implemented")]
387                 public virtual void RequireCompleteInit (IInternalConfigRecord configRecord)
388                 {
389                         throw new NotImplementedException ();
390                 }
391
392                 public virtual object StartMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
393                 {
394                         throw new NotImplementedException ();
395                 }
396                 
397                 public virtual void StopMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
398                 {
399                         throw new NotImplementedException ();
400                 }
401                 
402                 public virtual void VerifyDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition, IConfigErrorInfo errorInfo)
403                 {
404                         if (!IsDefinitionAllowed (configPath, allowDefinition, allowExeDefinition))
405                                 throw new ConfigurationErrorsException ("The section can't be defined in this file (the allowed definition context is '" + allowDefinition + "').", errorInfo.Filename, errorInfo.LineNumber);
406                 }
407                 
408                 [MonoTODO("Does nothing")]
409                 public virtual void WriteCompleted (string streamName, bool success, object writeContext)
410                 {
411                 }
412                 
413                 [MonoTODO("Does nothing")]
414                 public virtual void WriteCompleted (string streamName, bool success, object writeContext, bool assertPermissions)
415                 {
416                 }
417
418                 public virtual bool SupportsChangeNotifications {
419                         get { return false; }
420                 }
421                 
422                 public virtual bool SupportsLocation {
423                         get { return false; }
424                 }
425                 
426                 public virtual bool SupportsPath {
427                         get { return false; }
428                 }
429                 
430                 public virtual bool SupportsRefresh {
431                         get { return false; }
432                 }
433
434                 [MonoTODO("Always returns false")]
435                 public virtual bool IsRemote {
436                         get { return false; }
437                 }
438
439                 [MonoTODO ("Not implemented")]
440                 public virtual bool IsFullTrustSectionWithoutAptcaAllowed (IInternalConfigRecord configRecord)
441                 {
442                         throw new NotImplementedException ();
443                 }
444
445                 [MonoTODO ("Not implemented")]
446                 public virtual bool IsInitDelayed (IInternalConfigRecord configRecord)
447                 {
448                         throw new NotImplementedException ();
449                 }
450
451                 [MonoTODO ("Not implemented")]
452                 public virtual bool IsSecondaryRoot (string configPath)
453                 {
454                         throw new NotImplementedException ();
455                 }
456
457                 [MonoTODO ("Not implemented")]
458                 public virtual bool IsTrustedConfigPath (string configPath)
459                 {
460                         throw new NotImplementedException ();
461                 }
462         }
463 }
464
465 #endif