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) {
121 return "/web.config";
123 mdir = Path.GetDirectoryName (System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile);
126 mdir = Path.GetDirectoryName (map.MachineConfigFilename);
128 return GetWebConfigFileName (mdir);
131 string dir = MapPath (configPath);
132 return GetWebConfigFileName (dir);
135 public virtual string GetStreamNameForConfigSource (string streamName, string configSource)
137 throw new NotImplementedException ();
140 public virtual object GetStreamVersion (string streamName)
142 throw new NotImplementedException ();
145 public virtual IDisposable Impersonate ()
147 throw new NotImplementedException ();
150 public virtual void Init (IInternalConfigRoot root, params object[] hostInitParams)
154 public virtual void InitForConfiguration (ref string locationSubPath, out string configPath, out string locationConfigPath, IInternalConfigRoot root, params object[] hostInitConfigurationParams)
156 string fullPath = (string) hostInitConfigurationParams [1];
158 map = (WebConfigurationFileMap) hostInitConfigurationParams [0];
160 if (locationSubPath == MachineWebPath) {
161 locationSubPath = MachinePath;
162 configPath = MachineWebPath;
163 locationConfigPath = null;
165 else if (locationSubPath == MachinePath) {
166 locationSubPath = null;
167 configPath = MachinePath;
168 locationConfigPath = null;
173 if (locationSubPath == null)
174 configPath = fullPath;
176 configPath = locationSubPath;
178 if (configPath == HttpRuntime.AppDomainAppVirtualPath
179 || configPath == "/")
182 i = configPath.LastIndexOf ("/");
185 locationConfigPath = configPath.Substring (i+1);
188 locationSubPath = "/";
190 locationSubPath = fullPath.Substring (0, i);
192 locationSubPath = MachineWebPath;
193 locationConfigPath = null;
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);
205 else if (HttpRuntime.AppDomainAppVirtualPath != null && virtualPath.StartsWith (HttpRuntime.AppDomainAppVirtualPath)) {
206 if (virtualPath == HttpRuntime.AppDomainAppVirtualPath)
207 return HttpRuntime.AppDomainAppPath;
208 return UrlUtils.Combine (HttpRuntime.AppDomainAppPath, virtualPath.Substring (HttpRuntime.AppDomainAppVirtualPath.Length));
214 public string NormalizeVirtualPath (string virtualPath)
216 if (virtualPath == null || virtualPath.Length == 0)
219 virtualPath = virtualPath.Trim ();
221 if (virtualPath [0] == '~' && virtualPath.Length > 2 && virtualPath [1] == '/')
222 virtualPath = virtualPath.Substring (1);
224 if (System.IO.Path.DirectorySeparatorChar != '/')
225 virtualPath = virtualPath.Replace (System.IO.Path.DirectorySeparatorChar, '/');
227 if (UrlUtils.IsRooted (virtualPath)) {
228 virtualPath = UrlUtils.Canonic (virtualPath);
230 if (map.VirtualDirectories.Count > 0) {
231 string root = map.VirtualDirectories [0].VirtualDirectory;
232 virtualPath = UrlUtils.Combine (root, virtualPath);
233 virtualPath = UrlUtils.Canonic (virtualPath);
239 public string MapPathFromMapper (string virtualPath)
241 string path = NormalizeVirtualPath (virtualPath);
243 foreach (VirtualDirectoryMapping mapping in map.VirtualDirectories) {
244 if (path.StartsWith (mapping.VirtualDirectory)) {
245 int i = mapping.VirtualDirectory.Length;
246 if (path.Length == i) {
247 return mapping.PhysicalDirectory;
249 else if (path [i] == '/') {
250 string pathPart = path.Substring (i + 1).Replace ('/', Path.DirectorySeparatorChar);
251 return Path.Combine (mapping.PhysicalDirectory, pathPart);
255 throw new HttpException ("Invalid virtual directory: " + virtualPath);
258 string GetWebConfigFileName (string dir)
260 string[] filenames = new string[] {"Web.Config", "Web.config", "web.config" };
262 foreach (string fn in filenames) {
263 string file = Path.Combine (dir, fn);
264 if (File.Exists (file))
271 public virtual bool IsAboveApplication (string configPath)
273 throw new NotImplementedException ();
276 public virtual bool IsConfigRecordRequired (string configPath)
278 throw new NotImplementedException ();
281 public virtual bool IsDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition)
283 switch (allowDefinition) {
284 case ConfigurationAllowDefinition.MachineOnly:
285 return configPath == MachinePath || configPath == MachineWebPath;
286 case ConfigurationAllowDefinition.MachineToWebRoot:
287 case ConfigurationAllowDefinition.MachineToApplication:
288 return configPath == MachinePath || configPath == MachineWebPath || configPath == "/";
294 public virtual bool IsFile (string streamName)
296 throw new NotImplementedException ();
299 public virtual bool IsLocationApplicable (string configPath)
301 throw new NotImplementedException ();
304 public virtual Stream OpenStreamForRead (string streamName)
306 if (!File.Exists (streamName)) {
308 if (streamName != null && (streamName.EndsWith ("machine.config") || streamName.EndsWith ("web.config"))) {
309 if (streamName.StartsWith ("/"))
310 streamName = streamName.Substring (1);
311 java.lang.ClassLoader cl = (java.lang.ClassLoader) AppDomain.CurrentDomain.GetData ("GH_ContextClassLoader");
313 java.io.InputStream inputStream = cl.getResourceAsStream (streamName);
314 return (Stream) vmw.common.IOUtils.getStream (inputStream);
318 throw new ConfigurationException ("File '" + streamName + "' not found");
321 return new FileStream (streamName, FileMode.Open, FileAccess.Read);
325 public virtual Stream OpenStreamForRead (string streamName, bool assertPermissions)
327 throw new NotImplementedException ();
330 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext)
332 return new FileStream (streamName, FileMode.Create, FileAccess.Write);
336 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext, bool assertPermissions)
338 throw new NotImplementedException ();
341 public virtual bool PrefetchAll (string configPath, string streamName)
343 throw new NotImplementedException ();
346 public virtual bool PrefetchSection (string sectionGroupName, string sectionName)
348 throw new NotImplementedException ();
352 public virtual void RequireCompleteInit (IInternalConfigRecord configRecord)
354 throw new NotImplementedException ();
357 public virtual object StartMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
359 throw new NotImplementedException ();
362 public virtual void StopMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
364 throw new NotImplementedException ();
367 public virtual void VerifyDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition, IConfigErrorInfo errorInfo)
369 if (!IsDefinitionAllowed (configPath, allowDefinition, allowExeDefinition))
370 throw new ConfigurationErrorsException ("The section can't be defined in this file (the allowed definition context is '" + allowDefinition + "').", errorInfo.Filename, errorInfo.LineNumber);
373 public virtual void WriteCompleted (string streamName, bool success, object writeContext)
378 public virtual void WriteCompleted (string streamName, bool success, object writeContext, bool assertPermissions)
382 public virtual bool SupportsChangeNotifications {
383 get { return false; }
386 public virtual bool SupportsLocation {
387 get { return false; }
390 public virtual bool SupportsPath {
391 get { return false; }
394 public virtual bool SupportsRefresh {
395 get { return false; }
399 public virtual bool IsRemote {
400 get { return false; }
404 public virtual bool IsFullTrustSectionWithoutAptcaAllowed (IInternalConfigRecord configRecord)
406 throw new NotImplementedException ();
410 public virtual bool IsInitDelayed (IInternalConfigRecord configRecord)
412 throw new NotImplementedException ();
416 public virtual bool IsSecondaryRoot (string configPath)
418 throw new NotImplementedException ();
422 public virtual bool IsTrustedConfigPath (string configPath)
424 throw new NotImplementedException ();