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)
33 using System.Security;
34 using System.Configuration;
35 using System.Configuration.Internal;
36 using System.Web.Util;
39 * this class needs to be rewritten to support usage of the
40 * IRemoteWebConfigurationHostServer interface. Once that's done, we
41 * need an implementation of that interface that talks (through a web
42 * service?) to a remote site..
44 * for now, though, just implement it as we do
45 * System.Configuration.InternalConfigurationHost, i.e. the local
48 namespace System.Web.Configuration
50 class WebConfigurationHost: IInternalConfigHost
52 WebConfigurationFileMap map;
53 const string MachinePath = ":machine:";
54 const string MachineWebPath = ":web:";
56 public virtual object CreateConfigurationContext (string configPath, string locationSubPath)
58 return new WebContext (WebApplicationLevel.AtApplication /* XXX */,
60 "" /* application path XXX */,
65 public virtual object CreateDeprecatedConfigContext (string configPath)
67 throw new NotImplementedException ();
70 public virtual string DecryptSection (string encryptedXml, ProtectedConfigurationProvider protectionProvider, ProtectedConfigurationSection protectedSection)
72 throw new NotImplementedException ();
75 public virtual void DeleteStream (string streamName)
77 File.Delete (streamName);
80 public virtual string EncryptSection (string encryptedXml, ProtectedConfigurationProvider protectionProvider, ProtectedConfigurationSection protectedSection)
82 throw new NotImplementedException ();
85 public virtual string GetConfigPathFromLocationSubPath (string configPath, string locatinSubPath)
87 return configPath + "/" + locatinSubPath;
90 public virtual Type GetConfigType (string typeName, bool throwOnError)
92 Type type = Type.GetType (typeName);
93 if (type == null && throwOnError)
94 throw new ConfigurationErrorsException ("Type not found: '" + typeName + "'");
98 public virtual string GetConfigTypeName (Type t)
100 return t.AssemblyQualifiedName;
103 public virtual void GetRestrictedPermissions (IInternalConfigRecord configRecord, out PermissionSet permissionSet, out bool isHostReady)
105 throw new NotImplementedException ();
108 public virtual string GetStreamName (string configPath)
110 if (configPath == MachinePath) {
112 return System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile;
114 return map.MachineConfigFilename;
115 } else if (configPath == MachineWebPath) {
119 mdir = Path.GetDirectoryName (System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile);
121 mdir = Path.GetDirectoryName (map.MachineConfigFilename);
123 return GetWebConfigFileName (mdir);
126 string dir = MapPath (configPath);
127 return GetWebConfigFileName (dir);
130 public virtual string GetStreamNameForConfigSource (string streamName, string configSource)
132 throw new NotImplementedException ();
135 public virtual object GetStreamVersion (string streamName)
137 throw new NotImplementedException ();
140 public virtual IDisposable Impersonate ()
142 throw new NotImplementedException ();
145 public virtual void Init (IInternalConfigRoot root, params object[] hostInitParams)
149 public virtual void InitForConfiguration (ref string locationSubPath, out string configPath, out string locationConfigPath, IInternalConfigRoot root, params object[] hostInitConfigurationParams)
151 string fullPath = (string) hostInitConfigurationParams [1];
153 map = (WebConfigurationFileMap) hostInitConfigurationParams [0];
155 if (locationSubPath == MachineWebPath) {
156 locationSubPath = MachinePath;
157 configPath = MachineWebPath;
158 locationConfigPath = null;
160 else if (locationSubPath == MachinePath) {
161 locationSubPath = null;
162 configPath = MachinePath;
163 locationConfigPath = null;
168 if (locationSubPath == null)
169 configPath = fullPath;
171 configPath = locationSubPath;
173 if (configPath == "/")
176 i = configPath.LastIndexOf ("/");
179 locationConfigPath = configPath.Substring (i+1);
182 locationSubPath = "/";
184 locationSubPath = fullPath.Substring (0, i);
186 locationSubPath = MachineWebPath;
187 locationConfigPath = null;
191 if (GetStreamName (configPath) == null) {
192 // There is no config file for this path. Get the next one in the chain.
193 InitForConfiguration (ref locationSubPath, out configPath, out locationConfigPath, root, hostInitConfigurationParams);
197 public string MapPath (string virtualPath)
200 return MapPathFromMapper (virtualPath);
201 else if (HttpContext.Current != null
202 && HttpContext.Current.Request != null)
203 return HttpContext.Current.Request.MapPath (virtualPath);
208 public string NormalizeVirtualPath (string virtualPath)
210 if (virtualPath == null || virtualPath.Length == 0)
213 virtualPath = virtualPath.Trim ();
215 if (virtualPath [0] == '~' && virtualPath.Length > 2 && virtualPath [1] == '/')
216 virtualPath = virtualPath.Substring (1);
218 if (System.IO.Path.DirectorySeparatorChar != '/')
219 virtualPath = virtualPath.Replace (System.IO.Path.DirectorySeparatorChar, '/');
221 if (UrlUtils.IsRooted (virtualPath)) {
222 virtualPath = UrlUtils.Canonic (virtualPath);
224 if (map.VirtualDirectories.Count > 0) {
225 string root = map.VirtualDirectories [0].VirtualDirectory;
226 virtualPath = UrlUtils.Combine (root, virtualPath);
227 virtualPath = UrlUtils.Canonic (virtualPath);
233 public string MapPathFromMapper (string virtualPath)
235 string path = NormalizeVirtualPath (virtualPath);
237 foreach (VirtualDirectoryMapping mapping in map.VirtualDirectories) {
238 if (path.StartsWith (mapping.VirtualDirectory)) {
239 int i = mapping.VirtualDirectory.Length;
240 if (path.Length == i) {
241 return mapping.PhysicalDirectory;
243 else if (path [i] == '/') {
244 string pathPart = path.Substring (i + 1).Replace ('/', Path.DirectorySeparatorChar);
245 return Path.Combine (mapping.PhysicalDirectory, pathPart);
249 throw new HttpException ("Invalid virtual directory: " + virtualPath);
252 string GetWebConfigFileName (string dir)
254 string[] filenames = new string[] {"Web.Config", "Web.config", "web.config" };
256 foreach (string fn in filenames) {
257 string file = Path.Combine (dir, fn);
258 if (File.Exists (file))
265 public virtual bool IsAboveApplication (string configPath)
267 throw new NotImplementedException ();
270 public virtual bool IsConfigRecordRequired (string configPath)
272 throw new NotImplementedException ();
275 public virtual bool IsDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition)
277 switch (allowDefinition) {
278 case ConfigurationAllowDefinition.MachineOnly:
279 return configPath == MachinePath || configPath == MachineWebPath;
280 case ConfigurationAllowDefinition.MachineToWebRoot:
281 case ConfigurationAllowDefinition.MachineToApplication:
282 return configPath == MachinePath || configPath == MachineWebPath || configPath == "/";
288 public virtual bool IsFile (string streamName)
290 throw new NotImplementedException ();
293 public virtual bool IsLocationApplicable (string configPath)
295 throw new NotImplementedException ();
298 public virtual Stream OpenStreamForRead (string streamName)
300 if (!File.Exists (streamName))
301 throw new ConfigurationException ("File '" + streamName + "' not found");
303 return new FileStream (streamName, FileMode.Open, FileAccess.Read);
307 public virtual Stream OpenStreamForRead (string streamName, bool assertPermissions)
309 throw new NotImplementedException ();
312 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext)
314 return new FileStream (streamName, FileMode.Create, FileAccess.Write);
318 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext, bool assertPermissions)
320 throw new NotImplementedException ();
323 public virtual bool PrefetchAll (string configPath, string streamName)
325 throw new NotImplementedException ();
328 public virtual bool PrefetchSection (string sectionGroupName, string sectionName)
330 throw new NotImplementedException ();
334 public virtual void RequireCompleteInit (IInternalConfigRecord configRecord)
336 throw new NotImplementedException ();
339 public virtual object StartMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
341 throw new NotImplementedException ();
344 public virtual void StopMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
346 throw new NotImplementedException ();
349 public virtual void VerifyDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition, IConfigErrorInfo errorInfo)
351 if (!IsDefinitionAllowed (configPath, allowDefinition, allowExeDefinition))
352 throw new ConfigurationErrorsException ("The section can't be defined in this file (the allowed definition context is '" + allowDefinition + "').", errorInfo.Filename, errorInfo.LineNumber);
355 public virtual void WriteCompleted (string streamName, bool success, object writeContext)
360 public virtual void WriteCompleted (string streamName, bool success, object writeContext, bool assertPermissions)
364 public virtual bool SupportsChangeNotifications {
365 get { return false; }
368 public virtual bool SupportsLocation {
369 get { return false; }
372 public virtual bool SupportsPath {
373 get { return false; }
376 public virtual bool SupportsRefresh {
377 get { return false; }
381 public virtual bool IsRemote {
382 get { return false; }
386 public virtual bool IsFullTrustSectionWithoutAptcaAllowed (IInternalConfigRecord configRecord)
388 throw new NotImplementedException ();
392 public virtual bool IsInitDelayed (IInternalConfigRecord configRecord)
394 throw new NotImplementedException ();
398 public virtual bool IsSecondaryRoot (string configPath)
400 throw new NotImplementedException ();
404 public virtual bool IsTrustedConfigPath (string configPath)
406 throw new NotImplementedException ();