2 // System.Web.Configuration.WebConfigurationHost.cs
5 // Lluis Sanchez Gual (lluis@novell.com)
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:
15 // The above copyright notice and this permission notice shall be
16 // included in all copies or substantial portions of the Software.
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.
26 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
32 using System.Collections;
34 using System.Security;
35 using System.Configuration;
36 using System.Configuration.Internal;
37 using System.Web.Util;
38 using System.Reflection;
41 * this class needs to be rewritten to support usage of the
42 * IRemoteWebConfigurationHostServer interface. Once that's done, we
43 * need an implementation of that interface that talks (through a web
44 * service?) to a remote site..
46 * for now, though, just implement it as we do
47 * System.Configuration.InternalConfigurationHost, i.e. the local
50 namespace System.Web.Configuration
52 class WebConfigurationHost: IInternalConfigHost
54 WebConfigurationFileMap map;
55 const string MachinePath = ":machine:";
56 const string MachineWebPath = ":web:";
58 public virtual object CreateConfigurationContext (string configPath, string locationSubPath)
60 return new WebContext (WebApplicationLevel.AtApplication /* XXX */,
62 "" /* application path XXX */,
67 public virtual object CreateDeprecatedConfigContext (string configPath)
69 throw new NotImplementedException ();
72 public virtual string DecryptSection (string encryptedXml, ProtectedConfigurationProvider protectionProvider,
73 ProtectedConfigurationSection protectedSection)
75 throw new NotImplementedException ();
78 public virtual void DeleteStream (string streamName)
80 File.Delete (streamName);
83 public virtual string EncryptSection (string encryptedXml, ProtectedConfigurationProvider protectionProvider,
84 ProtectedConfigurationSection protectedSection)
86 throw new NotImplementedException ();
89 public virtual string GetConfigPathFromLocationSubPath (string configPath, string locatinSubPath)
91 return configPath + "/" + locatinSubPath;
94 public virtual Type GetConfigType (string typeName, bool throwOnError)
96 Type type = HttpApplication.LoadType (typeName);
97 if (type == null && throwOnError)
98 throw new ConfigurationErrorsException ("Type not found: '" + typeName + "'");
102 public virtual string GetConfigTypeName (Type t)
104 return t.AssemblyQualifiedName;
107 public virtual void GetRestrictedPermissions (IInternalConfigRecord configRecord, out PermissionSet permissionSet,
108 out bool isHostReady)
110 throw new NotImplementedException ();
113 public virtual string GetStreamName (string configPath)
115 if (configPath == MachinePath) {
117 return System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile;
119 return map.MachineConfigFilename;
120 } else if (configPath == MachineWebPath) {
126 // check META-INF/web.config exists
127 java.lang.ClassLoader cl = (java.lang.ClassLoader) AppDomain.CurrentDomain.GetData ("GH_ContextClassLoader");
130 java.net.URL url = cl.getResource ("META-INF/web.config");
134 return "/META-INF/web.config";
137 mdir = Path.GetDirectoryName (System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile);
140 mdir = Path.GetDirectoryName (map.MachineConfigFilename);
142 return GetWebConfigFileName (mdir);
145 string dir = MapPath (configPath);
146 return GetWebConfigFileName (dir);
149 public virtual string GetStreamNameForConfigSource (string streamName, string configSource)
151 throw new NotImplementedException ();
154 public virtual object GetStreamVersion (string streamName)
156 throw new NotImplementedException ();
159 public virtual IDisposable Impersonate ()
161 throw new NotImplementedException ();
164 public virtual void Init (IInternalConfigRoot root, params object[] hostInitParams)
168 public virtual void InitForConfiguration (ref string locationSubPath, out string configPath,
169 out string locationConfigPath, IInternalConfigRoot root,
170 params object[] hostInitConfigurationParams)
172 string fullPath = (string) hostInitConfigurationParams [1];
173 map = (WebConfigurationFileMap) hostInitConfigurationParams [0];
175 if (locationSubPath == MachineWebPath) {
176 locationSubPath = MachinePath;
177 configPath = MachineWebPath;
178 locationConfigPath = null;
179 } else if (locationSubPath == MachinePath) {
180 locationSubPath = null;
181 configPath = MachinePath;
182 locationConfigPath = null;
185 if (locationSubPath == null)
187 configPath = fullPath;
188 if (configPath.Length > 1)
189 configPath = VirtualPathUtility.RemoveTrailingSlash (configPath);
192 configPath = locationSubPath;
194 if (configPath == HttpRuntime.AppDomainAppVirtualPath
195 || configPath == "/")
198 i = configPath.LastIndexOf ("/");
201 locationConfigPath = configPath.Substring (i+1);
204 locationSubPath = "/";
206 locationSubPath = fullPath.Substring (0, i);
208 locationSubPath = MachineWebPath;
209 locationConfigPath = null;
214 public string MapPath (string virtualPath)
217 return MapPathFromMapper (virtualPath);
218 else if (HttpContext.Current != null && HttpContext.Current.Request != null)
219 return HttpContext.Current.Request.MapPath (virtualPath);
220 else if (HttpRuntime.AppDomainAppVirtualPath != null &&
221 virtualPath.StartsWith (HttpRuntime.AppDomainAppVirtualPath)) {
222 if (virtualPath == HttpRuntime.AppDomainAppVirtualPath)
223 return HttpRuntime.AppDomainAppPath;
224 return UrlUtils.Combine (HttpRuntime.AppDomainAppPath,
225 virtualPath.Substring (HttpRuntime.AppDomainAppVirtualPath.Length));
231 public string NormalizeVirtualPath (string virtualPath)
233 if (virtualPath == null || virtualPath.Length == 0)
236 virtualPath = virtualPath.Trim ();
238 if (virtualPath [0] == '~' && virtualPath.Length > 2 && virtualPath [1] == '/')
239 virtualPath = virtualPath.Substring (1);
241 if (System.IO.Path.DirectorySeparatorChar != '/')
242 virtualPath = virtualPath.Replace (System.IO.Path.DirectorySeparatorChar, '/');
244 if (UrlUtils.IsRooted (virtualPath)) {
245 virtualPath = UrlUtils.Canonic (virtualPath);
247 if (map.VirtualDirectories.Count > 0) {
248 string root = map.VirtualDirectories [0].VirtualDirectory;
249 virtualPath = UrlUtils.Combine (root, virtualPath);
250 virtualPath = UrlUtils.Canonic (virtualPath);
256 public string MapPathFromMapper (string virtualPath)
258 string path = NormalizeVirtualPath (virtualPath);
260 foreach (VirtualDirectoryMapping mapping in map.VirtualDirectories) {
261 if (path.StartsWith (mapping.VirtualDirectory)) {
262 int i = mapping.VirtualDirectory.Length;
263 if (path.Length == i) {
264 return mapping.PhysicalDirectory;
266 else if (path [i] == '/') {
267 string pathPart = path.Substring (i + 1).Replace ('/', Path.DirectorySeparatorChar);
268 return Path.Combine (mapping.PhysicalDirectory, pathPart);
272 throw new HttpException ("Invalid virtual directory: " + virtualPath);
275 string GetWebConfigFileName (string dir)
278 DirectoryInfo d = GetCaseSensitiveExistingDirectory (new DirectoryInfo (dir));
282 FileInfo file = (FileInfo) FindByName ("web.config", d.GetFiles ("W*"));
284 file = (FileInfo) FindByName ("web.config", d.GetFiles ("w*"));
287 return file.FullName;
289 string[] filenames = new string[] {"Web.Config", "Web.config", "web.config" };
291 foreach (string fn in filenames) {
292 string file = Path.Combine (dir, fn);
293 if (File.Exists (file))
300 static DirectoryInfo GetCaseSensitiveExistingDirectory (DirectoryInfo dir) {
306 DirectoryInfo parent = GetCaseSensitiveExistingDirectory (dir.Parent);
310 return (DirectoryInfo) FindByName (dir.Name, parent.GetDirectories ());
313 static FileSystemInfo FindByName (string name, FileSystemInfo [] infos)
315 for (int i = 0; i < infos.Length; i++) {
316 if (String.Compare (name, infos [i].Name, StringComparison.OrdinalIgnoreCase) == 0)
322 public virtual bool IsAboveApplication (string configPath)
324 throw new NotImplementedException ();
327 public virtual bool IsConfigRecordRequired (string configPath)
329 throw new NotImplementedException ();
332 public virtual bool IsDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition,
333 ConfigurationAllowExeDefinition allowExeDefinition)
335 switch (allowDefinition) {
336 case ConfigurationAllowDefinition.MachineOnly:
337 return configPath == MachinePath || configPath == MachineWebPath;
338 case ConfigurationAllowDefinition.MachineToWebRoot:
339 case ConfigurationAllowDefinition.MachineToApplication:
340 return configPath == MachinePath || configPath == MachineWebPath || configPath == "/" ||
341 configPath == HttpRuntime.AppDomainAppVirtualPath;
347 public virtual bool IsFile (string streamName)
349 throw new NotImplementedException ();
352 public virtual bool IsLocationApplicable (string configPath)
354 throw new NotImplementedException ();
357 public virtual Stream OpenStreamForRead (string streamName)
359 if (!File.Exists (streamName)) {
361 if (streamName != null && (streamName.EndsWith ("machine.config") ||
362 streamName.EndsWith ("web.config"))) {
363 if (streamName.StartsWith ("/"))
364 streamName = streamName.Substring (1);
365 java.lang.ClassLoader cl = (java.lang.ClassLoader) AppDomain.CurrentDomain.GetData ("GH_ContextClassLoader");
367 java.io.InputStream inputStream = cl.getResourceAsStream (streamName);
368 return (Stream) vmw.common.IOUtils.getStream (inputStream);
372 throw new ConfigurationException ("File '" + streamName + "' not found");
375 return new FileStream (streamName, FileMode.Open, FileAccess.Read);
378 [MonoTODO ("Not implemented")]
379 public virtual Stream OpenStreamForRead (string streamName, bool assertPermissions)
381 throw new NotImplementedException ();
384 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext)
386 return new FileStream (streamName, FileMode.Create, FileAccess.Write);
389 [MonoTODO ("Not implemented")]
390 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext,
391 bool assertPermissions)
393 throw new NotImplementedException ();
396 public virtual bool PrefetchAll (string configPath, string streamName)
398 throw new NotImplementedException ();
401 public virtual bool PrefetchSection (string sectionGroupName, string sectionName)
403 throw new NotImplementedException ();
406 [MonoTODO ("Not implemented")]
407 public virtual void RequireCompleteInit (IInternalConfigRecord configRecord)
409 throw new NotImplementedException ();
412 public virtual object StartMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
414 throw new NotImplementedException ();
417 public virtual void StopMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
419 throw new NotImplementedException ();
422 public virtual void VerifyDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition,
423 ConfigurationAllowExeDefinition allowExeDefinition,
424 IConfigErrorInfo errorInfo)
426 if (!IsDefinitionAllowed (configPath, allowDefinition, allowExeDefinition))
427 throw new ConfigurationErrorsException ("The section can't be defined in this file (the allowed definition context is '" + allowDefinition + "').", errorInfo.Filename, errorInfo.LineNumber);
430 [MonoTODO("Does nothing")]
431 public virtual void WriteCompleted (string streamName, bool success, object writeContext)
435 [MonoTODO("Does nothing")]
436 public virtual void WriteCompleted (string streamName, bool success, object writeContext, bool assertPermissions)
440 public virtual bool SupportsChangeNotifications {
441 get { return false; }
444 public virtual bool SupportsLocation {
445 get { return false; }
448 public virtual bool SupportsPath {
449 get { return false; }
452 public virtual bool SupportsRefresh {
453 get { return false; }
456 [MonoTODO("Always returns false")]
457 public virtual bool IsRemote {
458 get { return false; }
461 [MonoTODO ("Not implemented")]
462 public virtual bool IsFullTrustSectionWithoutAptcaAllowed (IInternalConfigRecord configRecord)
464 throw new NotImplementedException ();
467 [MonoTODO ("Not implemented")]
468 public virtual bool IsInitDelayed (IInternalConfigRecord configRecord)
470 throw new NotImplementedException ();
473 [MonoTODO ("Not implemented")]
474 public virtual bool IsSecondaryRoot (string configPath)
476 throw new NotImplementedException ();
479 [MonoTODO ("Not implemented")]
480 public virtual bool IsTrustedConfigPath (string configPath)
482 throw new NotImplementedException ();