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) {
120 mdir = Path.GetDirectoryName (System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile);
122 mdir = Path.GetDirectoryName (map.MachineConfigFilename);
124 return GetWebConfigFileName (mdir);
127 string dir = MapPath (configPath);
128 return GetWebConfigFileName (dir);
131 public virtual string GetStreamNameForConfigSource (string streamName, string configSource)
133 throw new NotImplementedException ();
136 public virtual object GetStreamVersion (string streamName)
138 throw new NotImplementedException ();
141 public virtual IDisposable Impersonate ()
143 throw new NotImplementedException ();
146 public virtual void Init (IInternalConfigRoot root, params object[] hostInitParams)
150 public virtual void InitForConfiguration (ref string locationSubPath, out string configPath, out string locationConfigPath, IInternalConfigRoot root, params object[] hostInitConfigurationParams)
152 string fullPath = (string) hostInitConfigurationParams [1];
154 map = (WebConfigurationFileMap) hostInitConfigurationParams [0];
156 if (locationSubPath == MachineWebPath) {
157 locationSubPath = MachinePath;
158 configPath = MachineWebPath;
159 locationConfigPath = null;
161 else if (locationSubPath == MachinePath) {
162 locationSubPath = null;
163 configPath = MachinePath;
164 locationConfigPath = null;
169 if (locationSubPath == null)
170 configPath = fullPath;
172 configPath = locationSubPath;
174 if (configPath == HttpRuntime.AppDomainAppVirtualPath)
177 i = configPath.LastIndexOf ("/");
180 locationConfigPath = configPath.Substring (i+1);
183 locationSubPath = "/";
185 locationSubPath = fullPath.Substring (0, i);
187 locationSubPath = MachineWebPath;
188 locationConfigPath = null;
192 if (GetStreamName (configPath) == null) {
193 // There is no config file for this path. Get the next one in the chain.
194 InitForConfiguration (ref locationSubPath, out configPath, out locationConfigPath, root, hostInitConfigurationParams);
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 (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))
307 throw new ConfigurationException ("File '" + streamName + "' not found");
309 return new FileStream (streamName, FileMode.Open, FileAccess.Read);
313 public virtual Stream OpenStreamForRead (string streamName, bool assertPermissions)
315 throw new NotImplementedException ();
318 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext)
320 return new FileStream (streamName, FileMode.Create, FileAccess.Write);
324 public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext, bool assertPermissions)
326 throw new NotImplementedException ();
329 public virtual bool PrefetchAll (string configPath, string streamName)
331 throw new NotImplementedException ();
334 public virtual bool PrefetchSection (string sectionGroupName, string sectionName)
336 throw new NotImplementedException ();
340 public virtual void RequireCompleteInit (IInternalConfigRecord configRecord)
342 throw new NotImplementedException ();
345 public virtual object StartMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
347 throw new NotImplementedException ();
350 public virtual void StopMonitoringStreamForChanges (string streamName, StreamChangeCallback callback)
352 throw new NotImplementedException ();
355 public virtual void VerifyDefinitionAllowed (string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition, IConfigErrorInfo errorInfo)
357 if (!IsDefinitionAllowed (configPath, allowDefinition, allowExeDefinition))
358 throw new ConfigurationErrorsException ("The section can't be defined in this file (the allowed definition context is '" + allowDefinition + "').", errorInfo.Filename, errorInfo.LineNumber);
361 public virtual void WriteCompleted (string streamName, bool success, object writeContext)
366 public virtual void WriteCompleted (string streamName, bool success, object writeContext, bool assertPermissions)
370 public virtual bool SupportsChangeNotifications {
371 get { return false; }
374 public virtual bool SupportsLocation {
375 get { return false; }
378 public virtual bool SupportsPath {
379 get { return false; }
382 public virtual bool SupportsRefresh {
383 get { return false; }
387 public virtual bool IsRemote {
388 get { return false; }
392 public virtual bool IsFullTrustSectionWithoutAptcaAllowed (IInternalConfigRecord configRecord)
394 throw new NotImplementedException ();
398 public virtual bool IsInitDelayed (IInternalConfigRecord configRecord)
400 throw new NotImplementedException ();
404 public virtual bool IsSecondaryRoot (string configPath)
406 throw new NotImplementedException ();
410 public virtual bool IsTrustedConfigPath (string configPath)
412 throw new NotImplementedException ();