//
// Authors:
// Lluis Sanchez Gual (lluis@novell.com)
+// Marek Habersack <mhabersack@novell.com>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005-2009 Novell, Inc (http://www.novell.com)
//
-#if NET_2_0
using System;
+using System.Collections;
using System.IO;
using System.Security;
using System.Configuration;
using System.Configuration.Internal;
+using System.Web.Hosting;
using System.Web.Util;
using System.Reflection;
WebConfigurationFileMap map;
const string MachinePath = ":machine:";
const string MachineWebPath = ":web:";
+
+ string appVirtualPath;
public virtual object CreateConfigurationContext (string configPath, string locationSubPath)
{
public virtual object CreateDeprecatedConfigContext (string configPath)
{
- throw new NotImplementedException ();
+ return new HttpConfigurationContext(configPath);
}
public virtual string DecryptSection (string encryptedXml, ProtectedConfigurationProvider protectionProvider, ProtectedConfigurationSection protectedSection)
{
- throw new NotImplementedException ();
+ if (protectedSection == null)
+ throw new ArgumentNullException ("protectedSection");
+
+ return protectedSection.EncryptSection (encryptedXml, protectionProvider);
}
public virtual void DeleteStream (string streamName)
File.Delete (streamName);
}
- public virtual string EncryptSection (string encryptedXml, ProtectedConfigurationProvider protectionProvider, ProtectedConfigurationSection protectedSection)
- {
- throw new NotImplementedException ();
- }
-
- public virtual string GetConfigPathFromLocationSubPath (string configPath, string locatinSubPath)
+ public virtual string EncryptSection (string clearXml, ProtectedConfigurationProvider protectionProvider, ProtectedConfigurationSection protectedSection)
{
- return configPath + "/" + locatinSubPath;
- }
-
- private static string privateBinPath;
+ if (protectedSection == null)
+ throw new ArgumentNullException ("protectedSection");
- private static string PrivateBinPath {
- get {
- if (privateBinPath != null)
- return privateBinPath;
-
- AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
- privateBinPath = Path.Combine(setup.ApplicationBase, setup.PrivateBinPath);
- return privateBinPath;
- }
+ return protectedSection.EncryptSection (clearXml, protectionProvider);
}
- private Type LoadType(string typeName)
+ public virtual string GetConfigPathFromLocationSubPath (string configPath, string locationSubPath)
{
- Type type = Type.GetType (typeName);
- if (type != null)
- return type;
-
- if (!Directory.Exists (PrivateBinPath))
- return null;
-
- string[] binDlls = Directory.GetFiles(PrivateBinPath, "*.dll");
- foreach (string s in binDlls) {
- Assembly binA = Assembly.LoadFrom (s);
- type = binA.GetType (typeName);
- if (type == null)
- continue;
-
- return type;
+ if (!String.IsNullOrEmpty (locationSubPath) && !String.IsNullOrEmpty (configPath)) {
+ string relConfigPath = configPath.Length == 1 ? null : configPath.Substring (1) + "/";
+ if (relConfigPath != null && locationSubPath.StartsWith (relConfigPath, StringComparison.Ordinal))
+ locationSubPath = locationSubPath.Substring (relConfigPath.Length);
}
- return null;
+ string ret = configPath + "/" + locationSubPath;
+ if (!String.IsNullOrEmpty (ret) && ret [0] == '/')
+ return ret.Substring (1);
+
+ return ret;
}
public virtual Type GetConfigType (string typeName, bool throwOnError)
{
- Type type = LoadType(typeName);
+ Type type = HttpApplication.LoadType (typeName);
if (type == null && throwOnError)
throw new ConfigurationErrorsException ("Type not found: '" + typeName + "'");
return type;
return t.AssemblyQualifiedName;
}
- public virtual void GetRestrictedPermissions (IInternalConfigRecord configRecord, out PermissionSet permissionSet, out bool isHostReady)
+ public virtual void GetRestrictedPermissions (IInternalConfigRecord configRecord, out PermissionSet permissionSet,
+ out bool isHostReady)
{
throw new NotImplementedException ();
}
string mdir;
if (map == null)
-#if TARGET_JVM
- return null;
-#else
mdir = Path.GetDirectoryName (System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile);
-#endif
else
mdir = Path.GetDirectoryName (map.MachineConfigFilename);
{
}
- public virtual void InitForConfiguration (ref string locationSubPath, out string configPath, out string locationConfigPath, IInternalConfigRoot root, params object[] hostInitConfigurationParams)
+ public virtual void InitForConfiguration (ref string locationSubPath, out string configPath,
+ out string locationConfigPath, IInternalConfigRoot root,
+ params object[] hostInitConfigurationParams)
{
string fullPath = (string) hostInitConfigurationParams [1];
-
map = (WebConfigurationFileMap) hostInitConfigurationParams [0];
+ bool inAnotherApp = false;
+
+ if ((hostInitConfigurationParams.Length > 7)
+ && (hostInitConfigurationParams[7] is bool))
+ inAnotherApp = (bool) hostInitConfigurationParams[7];
+
+ if (inAnotherApp)
+ appVirtualPath = fullPath;
+ else
+ appVirtualPath = HttpRuntime.AppDomainAppVirtualPath;
if (locationSubPath == MachineWebPath) {
locationSubPath = MachinePath;
configPath = MachineWebPath;
locationConfigPath = null;
- }
- else if (locationSubPath == MachinePath) {
+ } else if (locationSubPath == MachinePath) {
locationSubPath = null;
configPath = MachinePath;
locationConfigPath = null;
- }
- else {
-
+ } else {
int i;
- if (locationSubPath == null)
+ if (locationSubPath == null) {
configPath = fullPath;
- else
+ if (configPath.Length > 1)
+ configPath = VirtualPathUtility.RemoveTrailingSlash (configPath);
+ } else
configPath = locationSubPath;
-
- if (configPath == HttpRuntime.AppDomainAppVirtualPath
- || configPath == "/")
+
+ if (configPath == HttpRuntime.AppDomainAppVirtualPath || configPath == "/")
i = -1;
else
i = configPath.LastIndexOf ("/");
-
+
if (i != -1) {
locationConfigPath = configPath.Substring (i+1);
public string MapPath (string virtualPath)
{
+ if (!String.IsNullOrEmpty (virtualPath)) {
+ if (virtualPath.StartsWith (System.Web.Compilation.BuildManager.FAKE_VIRTUAL_PATH_PREFIX, StringComparison.Ordinal))
+ return HttpRuntime.AppDomainAppPath;
+ }
+
if (map != null)
return MapPathFromMapper (virtualPath);
- else if (HttpContext.Current != null
- && HttpContext.Current.Request != null)
+ else if (HttpContext.Current != null && HttpContext.Current.Request != null)
return HttpContext.Current.Request.MapPath (virtualPath);
- else if (HttpRuntime.AppDomainAppVirtualPath != null && virtualPath.StartsWith (HttpRuntime.AppDomainAppVirtualPath)) {
+ else if (HttpRuntime.AppDomainAppVirtualPath != null &&
+ virtualPath.StartsWith (HttpRuntime.AppDomainAppVirtualPath)) {
if (virtualPath == HttpRuntime.AppDomainAppVirtualPath)
return HttpRuntime.AppDomainAppPath;
- return UrlUtils.Combine (HttpRuntime.AppDomainAppPath, virtualPath.Substring (HttpRuntime.AppDomainAppVirtualPath.Length));
+ return UrlUtils.Combine (HttpRuntime.AppDomainAppPath,
+ virtualPath.Substring (HttpRuntime.AppDomainAppVirtualPath.Length));
}
- else
- return virtualPath;
+
+ return virtualPath;
}
public string NormalizeVirtualPath (string virtualPath)
throw new HttpException ("Invalid virtual directory: " + virtualPath);
}
- string GetWebConfigFileName (string dir)
+ internal static string GetWebConfigFileName (string dir)
{
- string[] filenames = new string[] {"Web.Config", "Web.config", "web.config" };
+ AppDomain domain = AppDomain.CurrentDomain;
+ bool hosted = (domain.GetData (ApplicationHost.MonoHostedDataKey) as string) == "yes";
- foreach (string fn in filenames) {
- string file = Path.Combine (dir, fn);
- if (File.Exists (file))
- return file;
- }
+ if (hosted)
+ return ApplicationHost.FindWebConfig (dir);
+ else {
+ Assembly asm = Assembly.GetEntryAssembly () ?? Assembly.GetCallingAssembly ();
+ string name = Path.GetFileName (asm.Location);
+ string[] fileNames = new string[] {name + ".config", name + ".Config"};
+ string appDir = domain.BaseDirectory;
+ string file;
+ foreach (string fn in fileNames) {
+ file = Path.Combine (appDir, fn);
+ if (File.Exists (file))
+ return file;
+ }
+ }
return null;
}
-
public virtual bool IsAboveApplication (string configPath)
{
- throw new NotImplementedException ();
+ return !configPath.Contains (HttpRuntime.AppDomainAppPath);
}
public virtual bool IsConfigRecordRequired (string configPath)
throw new NotImplementedException ();
}
- public virtual bool IsDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition)
+ public virtual bool IsDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition,
+ ConfigurationAllowExeDefinition allowExeDefinition)
{
switch (allowDefinition) {
case ConfigurationAllowDefinition.MachineOnly:
return configPath == MachinePath || configPath == MachineWebPath;
case ConfigurationAllowDefinition.MachineToWebRoot:
case ConfigurationAllowDefinition.MachineToApplication:
- return configPath == MachinePath || configPath == MachineWebPath || configPath == "/";
+ if (String.IsNullOrEmpty (configPath))
+ return true;
+ string normalized;
+
+ if (VirtualPathUtility.IsRooted (configPath))
+ normalized = VirtualPathUtility.Normalize (configPath);
+ else
+ normalized = configPath;
+
+ if ((String.Compare (normalized, MachinePath, StringComparison.Ordinal) == 0) ||
+ (String.Compare (normalized, MachineWebPath, StringComparison.Ordinal) == 0))
+ return true;
+
+ if ((String.Compare (normalized, appVirtualPath) != 0))
+ return IsApplication (normalized);
+
+ return true;
default:
return true;
}
}
+ [MonoTODO("Should return false in case strPath points to the root of an application.")]
+ internal bool IsApplication(string strPath)
+ {
+ return true;
+ }
+
public virtual bool IsFile (string streamName)
{
throw new NotImplementedException ();
public virtual Stream OpenStreamForRead (string streamName)
{
if (!File.Exists (streamName)) {
-#if TARGET_J2EE
- if (streamName != null && (streamName.EndsWith ("machine.config") || streamName.EndsWith ("web.config"))) {
- if (streamName.StartsWith ("/"))
- streamName = streamName.Substring (1);
- java.lang.ClassLoader cl = (java.lang.ClassLoader) AppDomain.CurrentDomain.GetData ("GH_ContextClassLoader");
- if (cl != null) {
- java.io.InputStream inputStream = cl.getResourceAsStream (streamName);
- return (Stream) vmw.common.IOUtils.getStream (inputStream);
- }
- }
-#endif
- throw new ConfigurationException ("File '" + streamName + "' not found");
+ return null;
}
return new FileStream (streamName, FileMode.Open, FileAccess.Read);
public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext)
{
+ if (!IsAboveApplication (streamName))
+ WebConfigurationManager.SuppressAppReload (true);
+
return new FileStream (streamName, FileMode.Create, FileAccess.Write);
}
[MonoTODO ("Not implemented")]
- public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext, bool assertPermissions)
+ public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext,
+ bool assertPermissions)
{
throw new NotImplementedException ();
}
}
public virtual object StartMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
- {
+ {
throw new NotImplementedException ();
}
throw new NotImplementedException ();
}
- public virtual void VerifyDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition, IConfigErrorInfo errorInfo)
+ public virtual void VerifyDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition,
+ ConfigurationAllowExeDefinition allowExeDefinition,
+ IConfigErrorInfo errorInfo)
{
if (!IsDefinitionAllowed (configPath, allowDefinition, allowExeDefinition))
throw new ConfigurationErrorsException ("The section can't be defined in this file (the allowed definition context is '" + allowDefinition + "').", errorInfo.Filename, errorInfo.LineNumber);
}
- [MonoTODO("Does nothing")]
public virtual void WriteCompleted (string streamName, bool success, object writeContext)
{
- }
-
- [MonoTODO("Does nothing")]
+ WriteCompleted (streamName, success, writeContext, false);
+ }
+
public virtual void WriteCompleted (string streamName, bool success, object writeContext, bool assertPermissions)
{
+ // There are probably other things to be done here, but for the moment we
+ // just mark the completed write as one that should not cause application
+ // reload. Note that it might already be too late for suppression, since the
+ // FileSystemWatcher monitor might have already delivered the
+ // notification. If the stream has been open using OpenStreamForWrite then
+ // we're safe, though.
+
+ if (!IsAboveApplication (streamName))
+ WebConfigurationManager.SuppressAppReload (true);
}
public virtual bool SupportsChangeNotifications {
}
}
-#endif