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)
32 using System.Collections;
34 using System.Security;
35 using System.Configuration;
36 using System.Configuration.Internal;
37 using System.Web.Util;
38 using System.Reflection;
41 * this class needs to be rewritten to support usage of the
42 * IRemoteWebConfigurationHostServer interface. Once that's done, we
43 * need an implementation of that interface that talks (through a web
44 * service?) to a remote site..
46 * for now, though, just implement it as we do
47 * System.Configuration.InternalConfigurationHost, i.e. the local
50 namespace System.Web.Configuration
52 class WebConfigurationHost: IInternalConfigHost
54 WebConfigurationFileMap map;
55 const string MachinePath = ":machine:";
56 const string MachineWebPath = ":web:";
58 public virtual object CreateConfigurationContext (string configPath, string locationSubPath)
60 return new WebContext (WebApplicationLevel.AtApplication /* XXX */,
62 "" /* application path XXX */,
67 public virtual object CreateDeprecatedConfigContext (string configPath)
69 throw new NotImplementedException ();
72 public virtual string DecryptSection (string encryptedXml, ProtectedConfigurationProvider protectionProvider,
73 ProtectedConfigurationSection protectedSection)
75 throw new NotImplementedException ();
78 public virtual void DeleteStream (string streamName)
80 File.Delete (streamName);
83 public virtual string EncryptSection (string encryptedXml, ProtectedConfigurationProvider protectionProvider,
84 ProtectedConfigurationSection protectedSection)
86 throw new NotImplementedException ();
89 public virtual string GetConfigPathFromLocationSubPath (string configPath, string locatinSubPath)
91 return configPath + "/" + locatinSubPath;
94 private static string privateBinPath;
96 private static string PrivateBinPath {
98 if (privateBinPath != null)
99 return privateBinPath;
101 AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
102 privateBinPath = Path.Combine(setup.ApplicationBase, setup.PrivateBinPath);
103 return privateBinPath;
107 private Type LoadType(string typeName)
109 Type type = Type.GetType (typeName);
113 IList tla = System.Web.Compilation.BuildManager.TopLevelAssemblies;
114 if (tla != null && tla.Count > 0) {
115 foreach (Assembly asm in tla) {
118 type = asm.GetType (typeName, false);
126 if (!Directory.Exists (PrivateBinPath))
129 string[] binDlls = Directory.GetFiles(PrivateBinPath, "*.dll");
130 foreach (string s in binDlls) {
131 Assembly binA = Assembly.LoadFrom (s);
132 type = binA.GetType (typeName);
142 public virtual Type GetConfigType (string typeName, bool throwOnError)
144 Type type = LoadType(typeName);
145 if (type == null && throwOnError)
146 throw new ConfigurationErrorsException ("Type not found: '" + typeName + "'");
150 public virtual string GetConfigTypeName (Type t)
152 return t.AssemblyQualifiedName;
155 public virtual void GetRestrictedPermissions (IInternalConfigRecord configRecord, out PermissionSet permissionSet,
156 out bool isHostReady)
158 throw new NotImplementedException ();
161 public virtual string GetStreamName (string configPath)
163 if (configPath == MachinePath) {
165 return System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile;
167 return map.MachineConfigFilename;
168 } else if (configPath == MachineWebPath) {
173 return "/META-INF/web.config";
175 mdir = Path.GetDirectoryName (System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile);
178 mdir = Path.GetDirectoryName (map.MachineConfigFilename);
180 return GetWebConfigFileName (mdir);
184 string dir = MapPath (configPath);
185 return GetWebConfigFileName (dir);
186 } catch (Exception ex) {
187 throw new HttpException (400, "Bad Request");
191 public virtual string GetStreamNameForConfigSource (string streamName, string configSource)
193 throw new NotImplementedException ();
196 public virtual object GetStreamVersion (string streamName)
198 throw new NotImplementedException ();
201 public virtual IDisposable Impersonate ()
203 throw new NotImplementedException ();
206 public virtual void Init (IInternalConfigRoot root, params object[] hostInitParams)
210 public virtual void InitForConfiguration (ref string locationSubPath, out string configPath,
211 out string locationConfigPath, IInternalConfigRoot root,
212 params object[] hostInitConfigurationParams)
214 string fullPath = (string) hostInitConfigurationParams [1];
215 map = (WebConfigurationFileMap) hostInitConfigurationParams [0];
217 if (locationSubPath == MachineWebPath) {
218 locationSubPath = MachinePath;
219 configPath = MachineWebPath;
220 locationConfigPath = null;
221 } else if (locationSubPath == MachinePath) {
222 locationSubPath = null;
223 configPath = MachinePath;
224 locationConfigPath = null;
227 if (locationSubPath == null)
228 configPath = fullPath;
230 configPath = locationSubPath;
232 if (configPath == HttpRuntime.AppDomainAppVirtualPath
233 || configPath == "/")
236 i = configPath.LastIndexOf ("/");
239 locationConfigPath = configPath.Substring (i+1);
242 locationSubPath = "/";
244 locationSubPath = fullPath.Substring (0, i);
246 locationSubPath = MachineWebPath;
247 locationConfigPath = null;
252 public string MapPath (string virtualPath)
255 return MapPathFromMapper (virtualPath);
256 else if (HttpContext.Current != null && HttpContext.Current.Request != null)
257 return HttpContext.Current.Request.MapPath (virtualPath);
258 else if (HttpRuntime.AppDomainAppVirtualPath != null &&
259 virtualPath.StartsWith (HttpRuntime.AppDomainAppVirtualPath)) {
260 if (virtualPath == HttpRuntime.AppDomainAppVirtualPath)
261 return HttpRuntime.AppDomainAppPath;
262 return UrlUtils.Combine (HttpRuntime.AppDomainAppPath,
263 virtualPath.Substring (HttpRuntime.AppDomainAppVirtualPath.Length));
269 public string NormalizeVirtualPath (string virtualPath)
271 if (virtualPath == null || virtualPath.Length == 0)
274 virtualPath = virtualPath.Trim ();
276 if (virtualPath [0] == '~' && virtualPath.Length > 2 && virtualPath [1] == '/')
277 virtualPath = virtualPath.Substring (1);
279 if (System.IO.Path.DirectorySeparatorChar != '/')
280 virtualPath = virtualPath.Replace (System.IO.Path.DirectorySeparatorChar, '/');
282 if (UrlUtils.IsRooted (virtualPath)) {
283 virtualPath = UrlUtils.Canonic (virtualPath);
285 if (map.VirtualDirectories.Count > 0) {
286 string root = map.VirtualDirectories [0].VirtualDirectory;
287 virtualPath = UrlUtils.Combine (root, virtualPath);
288 virtualPath = UrlUtils.Canonic (virtualPath);
294 public string MapPathFromMapper (string virtualPath)
296 string path = NormalizeVirtualPath (virtualPath);
298 foreach (VirtualDirectoryMapping mapping in map.VirtualDirectories) {
299 if (path.StartsWith (mapping.VirtualDirectory)) {
300 int i = mapping.VirtualDirectory.Length;
301 if (path.Length == i) {
302 return mapping.PhysicalDirectory;
304 else if (path [i] == '/') {
305 string pathPart = path.Substring (i + 1).Replace ('/', Path.DirectorySeparatorChar);
306 return Path.Combine (mapping.PhysicalDirectory, pathPart);
310 throw new HttpException ("Invalid virtual directory: " + virtualPath);
313 string GetWebConfigFileName (string dir)
315 string[] filenames = new string[] {"Web.Config", "Web.config", "web.config" };
317 foreach (string fn in filenames) {
318 string file = Path.Combine (dir, fn);
319 if (File.Exists (file))
326 public virtual bool IsAboveApplication (string configPath)
328 throw new NotImplementedException ();
331 public virtual bool IsConfigRecordRequired (string configPath)
333 throw new NotImplementedException ();
336 public virtual bool IsDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition,
337 ConfigurationAllowExeDefinition allowExeDefinition)
339 switch (allowDefinition) {
340 case ConfigurationAllowDefinition.MachineOnly:
341 return configPath == MachinePath || configPath == MachineWebPath;
342 case ConfigurationAllowDefinition.MachineToWebRoot:
343 case ConfigurationAllowDefinition.MachineToApplication:
344 return configPath == MachinePath || configPath == MachineWebPath || configPath == "/" ||
345 configPath == HttpRuntime.AppDomainAppVirtualPath;
351 public virtual bool IsFile (string streamName)
353 throw new NotImplementedException ();
356 public virtual bool IsLocationApplicable (string configPath)
358 throw new NotImplementedException ();
361 public virtual Stream OpenStreamForRead (string streamName)
363 if (!File.Exists (streamName)) {
365 if (streamName != null && (streamName.EndsWith ("machine.config") ||
366 streamName.EndsWith ("web.config"))) {
367 if (streamName.StartsWith ("/"))
368 streamName = streamName.Substring (1);
369 java.lang.ClassLoader cl = (java.lang.ClassLoader) AppDomain.CurrentDomain.GetData ("GH_ContextClassLoader");
371 java.io.InputStream inputStream = cl.getResourceAsStream (streamName);
372 return (Stream) vmw.common.IOUtils.getStream (inputStream);
376 throw new ConfigurationException ("File '" + streamName + "' not found");
379 return new FileStream (streamName, FileMode.Open, FileAccess.Read);
382 [MonoTODO ("Not implemented")]
383 public virtual Stream OpenStreamForRead (string streamName, bool assertPermissions)
385 throw new NotImplementedException ();
388 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext)
390 return new FileStream (streamName, FileMode.Create, FileAccess.Write);
393 [MonoTODO ("Not implemented")]
394 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext,
395 bool assertPermissions)
397 throw new NotImplementedException ();
400 public virtual bool PrefetchAll (string configPath, string streamName)
402 throw new NotImplementedException ();
405 public virtual bool PrefetchSection (string sectionGroupName, string sectionName)
407 throw new NotImplementedException ();
410 [MonoTODO ("Not implemented")]
411 public virtual void RequireCompleteInit (IInternalConfigRecord configRecord)
413 throw new NotImplementedException ();
416 public virtual object StartMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
418 throw new NotImplementedException ();
421 public virtual void StopMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
423 throw new NotImplementedException ();
426 public virtual void VerifyDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition,
427 ConfigurationAllowExeDefinition allowExeDefinition,
428 IConfigErrorInfo errorInfo)
430 if (!IsDefinitionAllowed (configPath, allowDefinition, allowExeDefinition))
431 throw new ConfigurationErrorsException ("The section can't be defined in this file (the allowed definition context is '" + allowDefinition + "').", errorInfo.Filename, errorInfo.LineNumber);
434 [MonoTODO("Does nothing")]
435 public virtual void WriteCompleted (string streamName, bool success, object writeContext)
439 [MonoTODO("Does nothing")]
440 public virtual void WriteCompleted (string streamName, bool success, object writeContext, bool assertPermissions)
444 public virtual bool SupportsChangeNotifications {
445 get { return false; }
448 public virtual bool SupportsLocation {
449 get { return false; }
452 public virtual bool SupportsPath {
453 get { return false; }
456 public virtual bool SupportsRefresh {
457 get { return false; }
460 [MonoTODO("Always returns false")]
461 public virtual bool IsRemote {
462 get { return false; }
465 [MonoTODO ("Not implemented")]
466 public virtual bool IsFullTrustSectionWithoutAptcaAllowed (IInternalConfigRecord configRecord)
468 throw new NotImplementedException ();
471 [MonoTODO ("Not implemented")]
472 public virtual bool IsInitDelayed (IInternalConfigRecord configRecord)
474 throw new NotImplementedException ();
477 [MonoTODO ("Not implemented")]
478 public virtual bool IsSecondaryRoot (string configPath)
480 throw new NotImplementedException ();
483 [MonoTODO ("Not implemented")]
484 public virtual bool IsTrustedConfigPath (string configPath)
486 throw new NotImplementedException ();