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;
37 using System.Reflection;
40 * this class needs to be rewritten to support usage of the
41 * IRemoteWebConfigurationHostServer interface. Once that's done, we
42 * need an implementation of that interface that talks (through a web
43 * service?) to a remote site..
45 * for now, though, just implement it as we do
46 * System.Configuration.InternalConfigurationHost, i.e. the local
49 namespace System.Web.Configuration
51 class WebConfigurationHost: IInternalConfigHost
53 WebConfigurationFileMap map;
54 const string MachinePath = ":machine:";
55 const string MachineWebPath = ":web:";
57 public virtual object CreateConfigurationContext (string configPath, string locationSubPath)
59 return new WebContext (WebApplicationLevel.AtApplication /* XXX */,
61 "" /* application path XXX */,
66 public virtual object CreateDeprecatedConfigContext (string configPath)
68 throw new NotImplementedException ();
71 public virtual string DecryptSection (string encryptedXml, ProtectedConfigurationProvider protectionProvider,
72 ProtectedConfigurationSection protectedSection)
74 throw new NotImplementedException ();
77 public virtual void DeleteStream (string streamName)
79 File.Delete (streamName);
82 public virtual string EncryptSection (string encryptedXml, ProtectedConfigurationProvider protectionProvider,
83 ProtectedConfigurationSection protectedSection)
85 throw new NotImplementedException ();
88 public virtual string GetConfigPathFromLocationSubPath (string configPath, string locatinSubPath)
90 return configPath + "/" + locatinSubPath;
93 private static string privateBinPath;
95 private static string PrivateBinPath {
97 if (privateBinPath != null)
98 return privateBinPath;
100 AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
101 privateBinPath = Path.Combine(setup.ApplicationBase, setup.PrivateBinPath);
102 return privateBinPath;
106 private Type LoadType(string typeName)
108 Type type = Type.GetType (typeName);
112 if (!Directory.Exists (PrivateBinPath))
115 string[] binDlls = Directory.GetFiles(PrivateBinPath, "*.dll");
116 foreach (string s in binDlls) {
117 Assembly binA = Assembly.LoadFrom (s);
118 type = binA.GetType (typeName);
128 public virtual Type GetConfigType (string typeName, bool throwOnError)
130 Type type = LoadType(typeName);
131 if (type == null && throwOnError)
132 throw new ConfigurationErrorsException ("Type not found: '" + typeName + "'");
136 public virtual string GetConfigTypeName (Type t)
138 return t.AssemblyQualifiedName;
141 public virtual void GetRestrictedPermissions (IInternalConfigRecord configRecord, out PermissionSet permissionSet,
142 out bool isHostReady)
144 throw new NotImplementedException ();
147 public virtual string GetStreamName (string configPath)
149 if (configPath == MachinePath) {
151 return System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile;
153 return map.MachineConfigFilename;
154 } else if (configPath == MachineWebPath) {
159 return "/web.config";
161 mdir = Path.GetDirectoryName (System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile);
164 mdir = Path.GetDirectoryName (map.MachineConfigFilename);
166 return GetWebConfigFileName (mdir);
169 string dir = MapPath (configPath);
170 return GetWebConfigFileName (dir);
173 public virtual string GetStreamNameForConfigSource (string streamName, string configSource)
175 throw new NotImplementedException ();
178 public virtual object GetStreamVersion (string streamName)
180 throw new NotImplementedException ();
183 public virtual IDisposable Impersonate ()
185 throw new NotImplementedException ();
188 public virtual void Init (IInternalConfigRoot root, params object[] hostInitParams)
192 public virtual void InitForConfiguration (ref string locationSubPath, out string configPath,
193 out string locationConfigPath, IInternalConfigRoot root,
194 params object[] hostInitConfigurationParams)
196 string fullPath = (string) hostInitConfigurationParams [1];
197 map = (WebConfigurationFileMap) hostInitConfigurationParams [0];
199 if (locationSubPath == MachineWebPath) {
200 locationSubPath = MachinePath;
201 configPath = MachineWebPath;
202 locationConfigPath = null;
203 } else if (locationSubPath == MachinePath) {
204 locationSubPath = null;
205 configPath = MachinePath;
206 locationConfigPath = null;
209 if (locationSubPath == null)
210 configPath = fullPath;
212 configPath = locationSubPath;
214 if (configPath == HttpRuntime.AppDomainAppVirtualPath
215 || configPath == "/")
218 i = configPath.LastIndexOf ("/");
221 locationConfigPath = configPath.Substring (i+1);
224 locationSubPath = "/";
226 locationSubPath = fullPath.Substring (0, i);
228 locationSubPath = MachineWebPath;
229 locationConfigPath = null;
234 public string MapPath (string virtualPath)
237 return MapPathFromMapper (virtualPath);
238 else if (HttpContext.Current != null
239 && HttpContext.Current.Request != null)
240 return HttpContext.Current.Request.MapPath (virtualPath);
241 else if (HttpRuntime.AppDomainAppVirtualPath != null &&
242 virtualPath.StartsWith (HttpRuntime.AppDomainAppVirtualPath)) {
243 if (virtualPath == HttpRuntime.AppDomainAppVirtualPath)
244 return HttpRuntime.AppDomainAppPath;
245 return UrlUtils.Combine (HttpRuntime.AppDomainAppPath,
246 virtualPath.Substring (HttpRuntime.AppDomainAppVirtualPath.Length));
252 public string NormalizeVirtualPath (string virtualPath)
254 if (virtualPath == null || virtualPath.Length == 0)
257 virtualPath = virtualPath.Trim ();
259 if (virtualPath [0] == '~' && virtualPath.Length > 2 && virtualPath [1] == '/')
260 virtualPath = virtualPath.Substring (1);
262 if (System.IO.Path.DirectorySeparatorChar != '/')
263 virtualPath = virtualPath.Replace (System.IO.Path.DirectorySeparatorChar, '/');
265 if (UrlUtils.IsRooted (virtualPath)) {
266 virtualPath = UrlUtils.Canonic (virtualPath);
268 if (map.VirtualDirectories.Count > 0) {
269 string root = map.VirtualDirectories [0].VirtualDirectory;
270 virtualPath = UrlUtils.Combine (root, virtualPath);
271 virtualPath = UrlUtils.Canonic (virtualPath);
277 public string MapPathFromMapper (string virtualPath)
279 string path = NormalizeVirtualPath (virtualPath);
281 foreach (VirtualDirectoryMapping mapping in map.VirtualDirectories) {
282 if (path.StartsWith (mapping.VirtualDirectory)) {
283 int i = mapping.VirtualDirectory.Length;
284 if (path.Length == i) {
285 return mapping.PhysicalDirectory;
287 else if (path [i] == '/') {
288 string pathPart = path.Substring (i + 1).Replace ('/', Path.DirectorySeparatorChar);
289 return Path.Combine (mapping.PhysicalDirectory, pathPart);
293 throw new HttpException ("Invalid virtual directory: " + virtualPath);
296 string GetWebConfigFileName (string dir)
298 string[] filenames = new string[] {"Web.Config", "Web.config", "web.config" };
300 foreach (string fn in filenames) {
301 string file = Path.Combine (dir, fn);
302 if (File.Exists (file))
309 public virtual bool IsAboveApplication (string configPath)
311 throw new NotImplementedException ();
314 public virtual bool IsConfigRecordRequired (string configPath)
316 throw new NotImplementedException ();
319 public virtual bool IsDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition,
320 ConfigurationAllowExeDefinition allowExeDefinition)
322 switch (allowDefinition) {
323 case ConfigurationAllowDefinition.MachineOnly:
324 return configPath == MachinePath || configPath == MachineWebPath;
325 case ConfigurationAllowDefinition.MachineToWebRoot:
326 case ConfigurationAllowDefinition.MachineToApplication:
327 return configPath == MachinePath || configPath == MachineWebPath || configPath == "/" ||
328 configPath == HttpRuntime.AppDomainAppVirtualPath;
334 public virtual bool IsFile (string streamName)
336 throw new NotImplementedException ();
339 public virtual bool IsLocationApplicable (string configPath)
341 throw new NotImplementedException ();
344 public virtual Stream OpenStreamForRead (string streamName)
346 if (!File.Exists (streamName)) {
348 if (streamName != null && (streamName.EndsWith ("machine.config") ||
349 streamName.EndsWith ("web.config"))) {
350 if (streamName.StartsWith ("/"))
351 streamName = streamName.Substring (1);
352 java.lang.ClassLoader cl = (java.lang.ClassLoader) AppDomain.CurrentDomain.GetData ("GH_ContextClassLoader");
354 java.io.InputStream inputStream = cl.getResourceAsStream (streamName);
355 return (Stream) vmw.common.IOUtils.getStream (inputStream);
359 throw new ConfigurationException ("File '" + streamName + "' not found");
362 return new FileStream (streamName, FileMode.Open, FileAccess.Read);
365 [MonoTODO ("Not implemented")]
366 public virtual Stream OpenStreamForRead (string streamName, bool assertPermissions)
368 throw new NotImplementedException ();
371 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext)
373 return new FileStream (streamName, FileMode.Create, FileAccess.Write);
376 [MonoTODO ("Not implemented")]
377 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext,
378 bool assertPermissions)
380 throw new NotImplementedException ();
383 public virtual bool PrefetchAll (string configPath, string streamName)
385 throw new NotImplementedException ();
388 public virtual bool PrefetchSection (string sectionGroupName, string sectionName)
390 throw new NotImplementedException ();
393 [MonoTODO ("Not implemented")]
394 public virtual void RequireCompleteInit (IInternalConfigRecord configRecord)
396 throw new NotImplementedException ();
399 public virtual object StartMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
401 throw new NotImplementedException ();
404 public virtual void StopMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
406 throw new NotImplementedException ();
409 public virtual void VerifyDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition,
410 ConfigurationAllowExeDefinition allowExeDefinition,
411 IConfigErrorInfo errorInfo)
413 if (!IsDefinitionAllowed (configPath, allowDefinition, allowExeDefinition))
414 throw new ConfigurationErrorsException ("The section can't be defined in this file (the allowed definition context is '" + allowDefinition + "').", errorInfo.Filename, errorInfo.LineNumber);
417 [MonoTODO("Does nothing")]
418 public virtual void WriteCompleted (string streamName, bool success, object writeContext)
422 [MonoTODO("Does nothing")]
423 public virtual void WriteCompleted (string streamName, bool success, object writeContext, bool assertPermissions)
427 public virtual bool SupportsChangeNotifications {
428 get { return false; }
431 public virtual bool SupportsLocation {
432 get { return false; }
435 public virtual bool SupportsPath {
436 get { return false; }
439 public virtual bool SupportsRefresh {
440 get { return false; }
443 [MonoTODO("Always returns false")]
444 public virtual bool IsRemote {
445 get { return false; }
448 [MonoTODO ("Not implemented")]
449 public virtual bool IsFullTrustSectionWithoutAptcaAllowed (IInternalConfigRecord configRecord)
451 throw new NotImplementedException ();
454 [MonoTODO ("Not implemented")]
455 public virtual bool IsInitDelayed (IInternalConfigRecord configRecord)
457 throw new NotImplementedException ();
460 [MonoTODO ("Not implemented")]
461 public virtual bool IsSecondaryRoot (string configPath)
463 throw new NotImplementedException ();
466 [MonoTODO ("Not implemented")]
467 public virtual bool IsTrustedConfigPath (string configPath)
469 throw new NotImplementedException ();