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;
170 i = fullPath.LastIndexOf ("/");
172 configPath = locationSubPath;
173 if (locationSubPath != "/")
174 i = locationSubPath.LastIndexOf ('/');
180 locationConfigPath = configPath.Substring (i+1);
183 locationSubPath = "/";
185 locationSubPath = fullPath.Substring (0, i);
187 locationSubPath = MachineWebPath;
188 locationConfigPath = null;
192 if (GetStreamName (configPath) == null) {
193 // There is no config file for this path. Get the next one in the chain.
194 InitForConfiguration (ref locationSubPath, out configPath, out locationConfigPath, root, hostInitConfigurationParams);
198 public string MapPath (string virtualPath)
201 return MapPathFromMapper (virtualPath);
202 else if (HttpContext.Current != null
203 && HttpContext.Current.Request != null)
204 return HttpContext.Current.Request.MapPath (virtualPath);
209 public string NormalizeVirtualPath (string virtualPath)
211 if (virtualPath == null || virtualPath.Length == 0)
214 virtualPath = virtualPath.Trim ();
216 if (virtualPath [0] == '~' && virtualPath.Length > 2 && virtualPath [1] == '/')
217 virtualPath = virtualPath.Substring (1);
219 if (System.IO.Path.DirectorySeparatorChar != '/')
220 virtualPath = virtualPath.Replace (System.IO.Path.DirectorySeparatorChar, '/');
222 if (UrlUtils.IsRooted (virtualPath)) {
223 virtualPath = UrlUtils.Canonic (virtualPath);
225 if (map.VirtualDirectories.Count > 0) {
226 string root = map.VirtualDirectories [0].VirtualDirectory;
227 virtualPath = UrlUtils.Combine (root, virtualPath);
228 virtualPath = UrlUtils.Canonic (virtualPath);
234 public string MapPathFromMapper (string virtualPath)
236 string path = NormalizeVirtualPath (virtualPath);
238 foreach (VirtualDirectoryMapping mapping in map.VirtualDirectories) {
239 if (path.StartsWith (mapping.VirtualDirectory)) {
240 int i = mapping.VirtualDirectory.Length;
241 if (path.Length == i) {
242 return mapping.PhysicalDirectory;
244 else if (path [i] == '/') {
245 string pathPart = path.Substring (i + 1).Replace ('/', Path.DirectorySeparatorChar);
246 return Path.Combine (mapping.PhysicalDirectory, pathPart);
250 throw new HttpException ("Invalid virtual directory: " + virtualPath);
253 string GetWebConfigFileName (string dir)
255 string[] filenames = new string[] {"Web.Config", "Web.config", "web.config" };
257 foreach (string fn in filenames) {
258 string file = Path.Combine (dir, fn);
259 if (File.Exists (file))
266 public virtual bool IsAboveApplication (string configPath)
268 throw new NotImplementedException ();
271 public virtual bool IsConfigRecordRequired (string configPath)
273 throw new NotImplementedException ();
276 public virtual bool IsDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition)
278 switch (allowDefinition) {
279 case ConfigurationAllowDefinition.MachineOnly:
280 return configPath == MachinePath || configPath == MachineWebPath;
281 case ConfigurationAllowDefinition.MachineToWebRoot:
282 case ConfigurationAllowDefinition.MachineToApplication:
283 return configPath == MachinePath || configPath == MachineWebPath || configPath == "/";
289 public virtual bool IsFile (string streamName)
291 throw new NotImplementedException ();
294 public virtual bool IsLocationApplicable (string configPath)
296 throw new NotImplementedException ();
299 public virtual Stream OpenStreamForRead (string streamName)
301 if (!File.Exists (streamName))
302 throw new ConfigurationException ("File '" + streamName + "' not found");
304 return new FileStream (streamName, FileMode.Open, FileAccess.Read);
308 public virtual Stream OpenStreamForRead (string streamName, bool assertPermissions)
310 throw new NotImplementedException ();
313 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext)
315 return new FileStream (streamName, FileMode.Create, FileAccess.Write);
319 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext, bool assertPermissions)
321 throw new NotImplementedException ();
324 public virtual bool PrefetchAll (string configPath, string streamName)
326 throw new NotImplementedException ();
329 public virtual bool PrefetchSection (string sectionGroupName, string sectionName)
331 throw new NotImplementedException ();
335 public virtual void RequireCompleteInit (IInternalConfigRecord configRecord)
337 throw new NotImplementedException ();
340 public virtual object StartMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
342 throw new NotImplementedException ();
345 public virtual void StopMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
347 throw new NotImplementedException ();
350 public virtual void VerifyDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition, IConfigErrorInfo errorInfo)
352 if (!IsDefinitionAllowed (configPath, allowDefinition, allowExeDefinition))
353 throw new ConfigurationErrorsException ("The section can't be defined in this file (the allowed definition context is '" + allowDefinition + "').", errorInfo.Filename, errorInfo.LineNumber);
356 public virtual void WriteCompleted (string streamName, bool success, object writeContext)
361 public virtual void WriteCompleted (string streamName, bool success, object writeContext, bool assertPermissions)
365 public virtual bool SupportsChangeNotifications {
366 get { return false; }
369 public virtual bool SupportsLocation {
370 get { return false; }
373 public virtual bool SupportsPath {
374 get { return false; }
377 public virtual bool SupportsRefresh {
378 get { return false; }
382 public virtual bool IsRemote {
383 get { return false; }
387 public virtual bool IsFullTrustSectionWithoutAptcaAllowed (IInternalConfigRecord configRecord)
389 throw new NotImplementedException ();
393 public virtual bool IsInitDelayed (IInternalConfigRecord configRecord)
395 throw new NotImplementedException ();
399 public virtual bool IsSecondaryRoot (string configPath)
401 throw new NotImplementedException ();
405 public virtual bool IsTrustedConfigPath (string configPath)
407 throw new NotImplementedException ();