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) {
114 return "/machine.config";
116 return System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile;
119 return map.MachineConfigFilename;
120 } else if (configPath == MachineWebPath) {
125 return "/web.config";
127 mdir = Path.GetDirectoryName (System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile);
130 mdir = Path.GetDirectoryName (map.MachineConfigFilename);
132 return GetWebConfigFileName (mdir);
135 string dir = MapPath (configPath);
136 return GetWebConfigFileName (dir);
139 public virtual string GetStreamNameForConfigSource (string streamName, string configSource)
141 throw new NotImplementedException ();
144 public virtual object GetStreamVersion (string streamName)
146 throw new NotImplementedException ();
149 public virtual IDisposable Impersonate ()
151 throw new NotImplementedException ();
154 public virtual void Init (IInternalConfigRoot root, params object[] hostInitParams)
158 public virtual void InitForConfiguration (ref string locationSubPath, out string configPath, out string locationConfigPath, IInternalConfigRoot root, params object[] hostInitConfigurationParams)
160 string fullPath = (string) hostInitConfigurationParams [1];
162 map = (WebConfigurationFileMap) hostInitConfigurationParams [0];
164 if (locationSubPath == MachineWebPath) {
165 locationSubPath = MachinePath;
166 configPath = MachineWebPath;
167 locationConfigPath = null;
169 else if (locationSubPath == MachinePath) {
170 locationSubPath = null;
171 configPath = MachinePath;
172 locationConfigPath = null;
177 if (locationSubPath == null)
178 configPath = fullPath;
180 configPath = locationSubPath;
182 if (configPath == HttpRuntime.AppDomainAppVirtualPath
183 || configPath == "/")
186 i = configPath.LastIndexOf ("/");
189 locationConfigPath = configPath.Substring (i+1);
192 locationSubPath = "/";
194 locationSubPath = fullPath.Substring (0, i);
196 locationSubPath = MachineWebPath;
197 locationConfigPath = null;
201 if (GetStreamName (configPath) == null) {
202 // There is no config file for this path. Get the next one in the chain.
203 InitForConfiguration (ref locationSubPath, out configPath, out locationConfigPath, root, hostInitConfigurationParams);
207 public string MapPath (string virtualPath)
210 return MapPathFromMapper (virtualPath);
211 else if (HttpContext.Current != null
212 && HttpContext.Current.Request != null)
213 return HttpContext.Current.Request.MapPath (virtualPath);
214 else if (HttpRuntime.AppDomainAppVirtualPath != null && virtualPath.StartsWith (HttpRuntime.AppDomainAppVirtualPath)) {
215 if (virtualPath == HttpRuntime.AppDomainAppVirtualPath)
216 return HttpRuntime.AppDomainAppPath;
217 return UrlUtils.Combine (HttpRuntime.AppDomainAppPath, virtualPath.Substring (HttpRuntime.AppDomainAppVirtualPath.Length));
223 public string NormalizeVirtualPath (string virtualPath)
225 if (virtualPath == null || virtualPath.Length == 0)
228 virtualPath = virtualPath.Trim ();
230 if (virtualPath [0] == '~' && virtualPath.Length > 2 && virtualPath [1] == '/')
231 virtualPath = virtualPath.Substring (1);
233 if (System.IO.Path.DirectorySeparatorChar != '/')
234 virtualPath = virtualPath.Replace (System.IO.Path.DirectorySeparatorChar, '/');
236 if (UrlUtils.IsRooted (virtualPath)) {
237 virtualPath = UrlUtils.Canonic (virtualPath);
239 if (map.VirtualDirectories.Count > 0) {
240 string root = map.VirtualDirectories [0].VirtualDirectory;
241 virtualPath = UrlUtils.Combine (root, virtualPath);
242 virtualPath = UrlUtils.Canonic (virtualPath);
248 public string MapPathFromMapper (string virtualPath)
250 string path = NormalizeVirtualPath (virtualPath);
252 foreach (VirtualDirectoryMapping mapping in map.VirtualDirectories) {
253 if (path.StartsWith (mapping.VirtualDirectory)) {
254 int i = mapping.VirtualDirectory.Length;
255 if (path.Length == i) {
256 return mapping.PhysicalDirectory;
258 else if (path [i] == '/') {
259 string pathPart = path.Substring (i + 1).Replace ('/', Path.DirectorySeparatorChar);
260 return Path.Combine (mapping.PhysicalDirectory, pathPart);
264 throw new HttpException ("Invalid virtual directory: " + virtualPath);
267 string GetWebConfigFileName (string dir)
269 string[] filenames = new string[] {"Web.Config", "Web.config", "web.config" };
271 foreach (string fn in filenames) {
272 string file = Path.Combine (dir, fn);
273 if (File.Exists (file))
280 public virtual bool IsAboveApplication (string configPath)
282 throw new NotImplementedException ();
285 public virtual bool IsConfigRecordRequired (string configPath)
287 throw new NotImplementedException ();
290 public virtual bool IsDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition)
292 switch (allowDefinition) {
293 case ConfigurationAllowDefinition.MachineOnly:
294 return configPath == MachinePath || configPath == MachineWebPath;
295 case ConfigurationAllowDefinition.MachineToWebRoot:
296 case ConfigurationAllowDefinition.MachineToApplication:
297 return configPath == MachinePath || configPath == MachineWebPath || configPath == "/";
303 public virtual bool IsFile (string streamName)
305 throw new NotImplementedException ();
308 public virtual bool IsLocationApplicable (string configPath)
310 throw new NotImplementedException ();
313 public virtual Stream OpenStreamForRead (string streamName)
315 if (!File.Exists (streamName)) {
317 if (streamName != null && (streamName.EndsWith ("machine.config") || streamName.EndsWith ("web.config"))) {
318 if (streamName.StartsWith ("/"))
319 streamName = streamName.Substring (1);
320 java.lang.ClassLoader cl = (java.lang.ClassLoader) AppDomain.CurrentDomain.GetData ("GH_ContextClassLoader");
322 java.io.InputStream inputStream = cl.getResourceAsStream (streamName);
323 return (Stream) vmw.common.IOUtils.getStream (inputStream);
327 throw new ConfigurationException ("File '" + streamName + "' not found");
330 return new FileStream (streamName, FileMode.Open, FileAccess.Read);
334 public virtual Stream OpenStreamForRead (string streamName, bool assertPermissions)
336 throw new NotImplementedException ();
339 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext)
341 return new FileStream (streamName, FileMode.Create, FileAccess.Write);
345 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext, bool assertPermissions)
347 throw new NotImplementedException ();
350 public virtual bool PrefetchAll (string configPath, string streamName)
352 throw new NotImplementedException ();
355 public virtual bool PrefetchSection (string sectionGroupName, string sectionName)
357 throw new NotImplementedException ();
361 public virtual void RequireCompleteInit (IInternalConfigRecord configRecord)
363 throw new NotImplementedException ();
366 public virtual object StartMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
368 throw new NotImplementedException ();
371 public virtual void StopMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
373 throw new NotImplementedException ();
376 public virtual void VerifyDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition, IConfigErrorInfo errorInfo)
378 if (!IsDefinitionAllowed (configPath, allowDefinition, allowExeDefinition))
379 throw new ConfigurationErrorsException ("The section can't be defined in this file (the allowed definition context is '" + allowDefinition + "').", errorInfo.Filename, errorInfo.LineNumber);
382 public virtual void WriteCompleted (string streamName, bool success, object writeContext)
387 public virtual void WriteCompleted (string streamName, bool success, object writeContext, bool assertPermissions)
391 public virtual bool SupportsChangeNotifications {
392 get { return false; }
395 public virtual bool SupportsLocation {
396 get { return false; }
399 public virtual bool SupportsPath {
400 get { return false; }
403 public virtual bool SupportsRefresh {
404 get { return false; }
408 public virtual bool IsRemote {
409 get { return false; }
413 public virtual bool IsFullTrustSectionWithoutAptcaAllowed (IInternalConfigRecord configRecord)
415 throw new NotImplementedException ();
419 public virtual bool IsInitDelayed (IInternalConfigRecord configRecord)
421 throw new NotImplementedException ();
425 public virtual bool IsSecondaryRoot (string configPath)
427 throw new NotImplementedException ();
431 public virtual bool IsTrustedConfigPath (string configPath)
433 throw new NotImplementedException ();