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 [MonoTODO ("this should consult with the build provider machinery")]
91 public virtual Type GetConfigType (string typeName, bool throwOnError)
93 Type type = Type.GetType (typeName);
94 if (type == null && throwOnError)
95 throw new ConfigurationErrorsException ("Type not found: '" + typeName + "'");
99 public virtual string GetConfigTypeName (Type t)
101 return t.AssemblyQualifiedName;
104 public virtual void GetRestrictedPermissions (IInternalConfigRecord configRecord, out PermissionSet permissionSet, out bool isHostReady)
106 throw new NotImplementedException ();
109 public virtual string GetStreamName (string configPath)
111 if (configPath == MachinePath) {
113 return System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile;
115 return map.MachineConfigFilename;
116 } else if (configPath == MachineWebPath) {
120 mdir = Path.GetDirectoryName (System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile);
122 mdir = Path.GetDirectoryName (map.MachineConfigFilename);
124 return GetWebConfigFileName (mdir);
127 string dir = MapPath (configPath);
128 return GetWebConfigFileName (dir);
131 public virtual string GetStreamNameForConfigSource (string streamName, string configSource)
133 throw new NotImplementedException ();
136 public virtual object GetStreamVersion (string streamName)
138 throw new NotImplementedException ();
141 public virtual IDisposable Impersonate ()
143 throw new NotImplementedException ();
146 public virtual void Init (IInternalConfigRoot root, params object[] hostInitParams)
150 public virtual void InitForConfiguration (ref string locationSubPath, out string configPath, out string locationConfigPath, IInternalConfigRoot root, params object[] hostInitConfigurationParams)
152 string fullPath = (string) hostInitConfigurationParams [1];
154 map = (WebConfigurationFileMap) hostInitConfigurationParams [0];
156 if (locationSubPath == MachineWebPath) {
157 locationSubPath = MachinePath;
158 configPath = MachineWebPath;
159 locationConfigPath = null;
161 else if (locationSubPath == MachinePath) {
162 locationSubPath = null;
163 configPath = MachinePath;
164 locationConfigPath = null;
169 if (locationSubPath == null)
170 configPath = fullPath;
172 configPath = locationSubPath;
174 if (configPath == HttpRuntime.AppDomainAppVirtualPath
175 || configPath == "/")
178 i = configPath.LastIndexOf ("/");
181 locationConfigPath = configPath.Substring (i+1);
184 locationSubPath = "/";
186 locationSubPath = fullPath.Substring (0, i);
188 locationSubPath = MachineWebPath;
189 locationConfigPath = null;
193 if (GetStreamName (configPath) == null) {
194 // There is no config file for this path. Get the next one in the chain.
195 InitForConfiguration (ref locationSubPath, out configPath, out locationConfigPath, root, hostInitConfigurationParams);
199 public string MapPath (string virtualPath)
202 return MapPathFromMapper (virtualPath);
203 else if (HttpContext.Current != null
204 && HttpContext.Current.Request != null)
205 return HttpContext.Current.Request.MapPath (virtualPath);
206 else if (HttpRuntime.AppDomainAppVirtualPath != null && virtualPath.StartsWith (HttpRuntime.AppDomainAppVirtualPath)) {
207 if (virtualPath == HttpRuntime.AppDomainAppVirtualPath)
208 return HttpRuntime.AppDomainAppPath;
209 return UrlUtils.Combine (HttpRuntime.AppDomainAppPath, virtualPath.Substring (HttpRuntime.AppDomainAppVirtualPath.Length));
215 public string NormalizeVirtualPath (string virtualPath)
217 if (virtualPath == null || virtualPath.Length == 0)
220 virtualPath = virtualPath.Trim ();
222 if (virtualPath [0] == '~' && virtualPath.Length > 2 && virtualPath [1] == '/')
223 virtualPath = virtualPath.Substring (1);
225 if (System.IO.Path.DirectorySeparatorChar != '/')
226 virtualPath = virtualPath.Replace (System.IO.Path.DirectorySeparatorChar, '/');
228 if (UrlUtils.IsRooted (virtualPath)) {
229 virtualPath = UrlUtils.Canonic (virtualPath);
231 if (map.VirtualDirectories.Count > 0) {
232 string root = map.VirtualDirectories [0].VirtualDirectory;
233 virtualPath = UrlUtils.Combine (root, virtualPath);
234 virtualPath = UrlUtils.Canonic (virtualPath);
240 public string MapPathFromMapper (string virtualPath)
242 string path = NormalizeVirtualPath (virtualPath);
244 foreach (VirtualDirectoryMapping mapping in map.VirtualDirectories) {
245 if (path.StartsWith (mapping.VirtualDirectory)) {
246 int i = mapping.VirtualDirectory.Length;
247 if (path.Length == i) {
248 return mapping.PhysicalDirectory;
250 else if (path [i] == '/') {
251 string pathPart = path.Substring (i + 1).Replace ('/', Path.DirectorySeparatorChar);
252 return Path.Combine (mapping.PhysicalDirectory, pathPart);
256 throw new HttpException ("Invalid virtual directory: " + virtualPath);
259 string GetWebConfigFileName (string dir)
261 string[] filenames = new string[] {"Web.Config", "Web.config", "web.config" };
263 foreach (string fn in filenames) {
264 string file = Path.Combine (dir, fn);
265 if (File.Exists (file))
272 public virtual bool IsAboveApplication (string configPath)
274 throw new NotImplementedException ();
277 public virtual bool IsConfigRecordRequired (string configPath)
279 throw new NotImplementedException ();
282 public virtual bool IsDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition)
284 switch (allowDefinition) {
285 case ConfigurationAllowDefinition.MachineOnly:
286 return configPath == MachinePath || configPath == MachineWebPath;
287 case ConfigurationAllowDefinition.MachineToWebRoot:
288 case ConfigurationAllowDefinition.MachineToApplication:
289 return configPath == MachinePath || configPath == MachineWebPath || configPath == "/";
295 public virtual bool IsFile (string streamName)
297 throw new NotImplementedException ();
300 public virtual bool IsLocationApplicable (string configPath)
302 throw new NotImplementedException ();
305 public virtual Stream OpenStreamForRead (string streamName)
307 if (!File.Exists (streamName))
308 throw new ConfigurationException ("File '" + streamName + "' not found");
310 return new FileStream (streamName, FileMode.Open, FileAccess.Read);
314 public virtual Stream OpenStreamForRead (string streamName, bool assertPermissions)
316 throw new NotImplementedException ();
319 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext)
321 return new FileStream (streamName, FileMode.Create, FileAccess.Write);
325 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext, bool assertPermissions)
327 throw new NotImplementedException ();
330 public virtual bool PrefetchAll (string configPath, string streamName)
332 throw new NotImplementedException ();
335 public virtual bool PrefetchSection (string sectionGroupName, string sectionName)
337 throw new NotImplementedException ();
341 public virtual void RequireCompleteInit (IInternalConfigRecord configRecord)
343 throw new NotImplementedException ();
346 public virtual object StartMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
348 throw new NotImplementedException ();
351 public virtual void StopMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
353 throw new NotImplementedException ();
356 public virtual void VerifyDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition, IConfigErrorInfo errorInfo)
358 if (!IsDefinitionAllowed (configPath, allowDefinition, allowExeDefinition))
359 throw new ConfigurationErrorsException ("The section can't be defined in this file (the allowed definition context is '" + allowDefinition + "').", errorInfo.Filename, errorInfo.LineNumber);
362 public virtual void WriteCompleted (string streamName, bool success, object writeContext)
367 public virtual void WriteCompleted (string streamName, bool success, object writeContext, bool assertPermissions)
371 public virtual bool SupportsChangeNotifications {
372 get { return false; }
375 public virtual bool SupportsLocation {
376 get { return false; }
379 public virtual bool SupportsPath {
380 get { return false; }
383 public virtual bool SupportsRefresh {
384 get { return false; }
388 public virtual bool IsRemote {
389 get { return false; }
393 public virtual bool IsFullTrustSectionWithoutAptcaAllowed (IInternalConfigRecord configRecord)
395 throw new NotImplementedException ();
399 public virtual bool IsInitDelayed (IInternalConfigRecord configRecord)
401 throw new NotImplementedException ();
405 public virtual bool IsSecondaryRoot (string configPath)
407 throw new NotImplementedException ();
411 public virtual bool IsTrustedConfigPath (string configPath)
413 throw new NotImplementedException ();