You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@@ -0,0 +1,117 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Xaml.Hosting.Configuration
|
||||
{
|
||||
using System;
|
||||
using System.Web;
|
||||
using System.Configuration;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime;
|
||||
|
||||
public sealed class HandlerElement : ConfigurationElement
|
||||
{
|
||||
static ConfigurationPropertyCollection properties = InitializeProperties();
|
||||
|
||||
Type httpHandlerCLRType;
|
||||
|
||||
Type xamlRootElementClrType;
|
||||
|
||||
static ConfigurationPropertyCollection InitializeProperties()
|
||||
{
|
||||
ConfigurationProperty handler = new ConfigurationProperty(XamlHostingConfiguration.HttpHandlerType, typeof(string), " ", null, new StringValidator(1), ConfigurationPropertyOptions.IsRequired);
|
||||
ConfigurationProperty xamlRoot = new ConfigurationProperty(XamlHostingConfiguration.XamlRootElementType, typeof(string), " ", null, new StringValidator(1), ConfigurationPropertyOptions.IsKey | ConfigurationPropertyOptions.IsRequired);
|
||||
ConfigurationPropertyCollection tempProperties = new ConfigurationPropertyCollection();
|
||||
tempProperties.Add(xamlRoot);
|
||||
tempProperties.Add(handler);
|
||||
return tempProperties;
|
||||
}
|
||||
|
||||
public HandlerElement()
|
||||
{
|
||||
}
|
||||
|
||||
[SuppressMessage(FxCop.Category.Usage, FxCop.Rule.DoNotCallOverridableMethodsInConstructors,
|
||||
Justification = "This is enforced by configuration classes in framework library")]
|
||||
public HandlerElement(string xamlType, string handlerType)
|
||||
{
|
||||
XamlRootElementType = xamlType;
|
||||
HttpHandlerType = handlerType;
|
||||
}
|
||||
|
||||
[ConfigurationProperty(XamlHostingConfiguration.HttpHandlerType, DefaultValue = " ",
|
||||
Options = ConfigurationPropertyOptions.IsRequired)]
|
||||
[StringValidator(MinLength = 1)]
|
||||
public string HttpHandlerType
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)base[XamlHostingConfiguration.HttpHandlerType];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
value = string.Empty;
|
||||
}
|
||||
base[XamlHostingConfiguration.HttpHandlerType] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty(XamlHostingConfiguration.XamlRootElementType, DefaultValue = " ",
|
||||
Options = ConfigurationPropertyOptions.IsKey | ConfigurationPropertyOptions.IsRequired)]
|
||||
[StringValidator(MinLength = 1)]
|
||||
public string XamlRootElementType
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)base[XamlHostingConfiguration.XamlRootElementType];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
value = string.Empty;
|
||||
}
|
||||
base[XamlHostingConfiguration.XamlRootElementType] = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal string Key
|
||||
{
|
||||
get
|
||||
{
|
||||
return XamlRootElementType;
|
||||
}
|
||||
}
|
||||
|
||||
protected override ConfigurationPropertyCollection Properties
|
||||
{
|
||||
get
|
||||
{
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
|
||||
internal Type LoadHttpHandlerType()
|
||||
{
|
||||
if (this.httpHandlerCLRType == null)
|
||||
{
|
||||
this.httpHandlerCLRType = Type.GetType(HttpHandlerType, true);
|
||||
}
|
||||
return this.httpHandlerCLRType;
|
||||
}
|
||||
|
||||
|
||||
internal Type LoadXamlRootElementType()
|
||||
{
|
||||
if (this.xamlRootElementClrType == null)
|
||||
{
|
||||
this.xamlRootElementClrType = Type.GetType(XamlRootElementType, true);
|
||||
}
|
||||
return this.xamlRootElementClrType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,131 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Xaml.Hosting.Configuration
|
||||
{
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Collections.Generic;
|
||||
using System.Web;
|
||||
using System.Runtime;
|
||||
|
||||
[ConfigurationCollection(typeof(HandlerElement), CollectionType = ConfigurationElementCollectionType.AddRemoveClearMapAlternate)]
|
||||
public sealed class HandlerElementCollection : ConfigurationElementCollection
|
||||
{
|
||||
public HandlerElementCollection()
|
||||
: base(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
}
|
||||
|
||||
public override ConfigurationElementCollectionType CollectionType
|
||||
{
|
||||
get
|
||||
{
|
||||
return ConfigurationElementCollectionType.AddRemoveClearMapAlternate;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool ThrowOnDuplicate
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public HandlerElement this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return (HandlerElement)base.BaseGet(index);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (base.BaseGet(index) != null)
|
||||
{
|
||||
base.BaseRemoveAt(index);
|
||||
}
|
||||
this.BaseAdd(index, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(HandlerElement handlerElement)
|
||||
{
|
||||
if (!this.IsReadOnly())
|
||||
{
|
||||
if (handlerElement == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull("handlerElement");
|
||||
}
|
||||
}
|
||||
|
||||
this.BaseAdd(handlerElement, false);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
base.BaseClear();
|
||||
}
|
||||
|
||||
public void Remove(HandlerElement handlerElement)
|
||||
{
|
||||
if (!this.IsReadOnly())
|
||||
{
|
||||
if (handlerElement == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull("handlerElement");
|
||||
}
|
||||
}
|
||||
|
||||
this.BaseRemove(this.GetElementKey(handlerElement));
|
||||
}
|
||||
|
||||
public void Remove(string xamlRootElementType)
|
||||
{
|
||||
if (!this.IsReadOnly())
|
||||
{
|
||||
if (xamlRootElementType == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull("xamlRootElementType");
|
||||
}
|
||||
}
|
||||
|
||||
this.BaseRemove(xamlRootElementType);
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
base.BaseRemoveAt(index);
|
||||
}
|
||||
|
||||
internal bool TryGetHttpHandlerType(Type hostedXamlType, out Type httpHandlerType)
|
||||
{
|
||||
httpHandlerType = null;
|
||||
foreach (HandlerElement handler in this)
|
||||
{
|
||||
if (handler.LoadXamlRootElementType().IsAssignableFrom(hostedXamlType))
|
||||
{
|
||||
httpHandlerType = handler.LoadHttpHandlerType();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override ConfigurationElement CreateNewElement()
|
||||
{
|
||||
return new HandlerElement();
|
||||
}
|
||||
|
||||
protected override object GetElementKey(ConfigurationElement element)
|
||||
{
|
||||
if (element == null)
|
||||
{
|
||||
throw FxTrace.Exception.ArgumentNull("element");
|
||||
}
|
||||
return ((HandlerElement)element).Key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,39 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Xaml.Hosting.Configuration
|
||||
{
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Web.Configuration;
|
||||
using System.Runtime;
|
||||
using System.Security;
|
||||
|
||||
static class XamlHostingConfiguration
|
||||
{
|
||||
internal const string CollectionName = "";
|
||||
internal const string HttpHandlerType = "httpHandlerType";
|
||||
internal const string XamlHostingConfigGroup = @"system.xaml.hosting";
|
||||
internal const string XamlHostingSection = XamlHostingConfigGroup + "/httpHandlers";
|
||||
internal const string XamlRootElementType = "xamlRootElementType";
|
||||
|
||||
internal static bool TryGetHttpHandlerType(string virtualPath, Type hostedXamlType, out Type httpHandlerType)
|
||||
{
|
||||
XamlHostingSection section = LoadXamlHostingSection(virtualPath);
|
||||
if (null == section)
|
||||
{
|
||||
ConfigurationErrorsException configException = new ConfigurationErrorsException(SR.ConfigSectionNotFound);
|
||||
throw FxTrace.Exception.AsError(configException);
|
||||
}
|
||||
return section.Handlers.TryGetHttpHandlerType(hostedXamlType, out httpHandlerType);
|
||||
}
|
||||
|
||||
static XamlHostingSection LoadXamlHostingSection(string virtualPath)
|
||||
{
|
||||
//WebConfigurationManager returns the same section object for a given virtual directory (not virtual path).
|
||||
return (XamlHostingSection)WebConfigurationManager.GetSection(XamlHostingConfiguration.XamlHostingSection, virtualPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,24 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Xaml.Hosting.Configuration
|
||||
{
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Runtime;
|
||||
using System.Web;
|
||||
|
||||
public sealed class XamlHostingSection : ConfigurationSection
|
||||
{
|
||||
[ConfigurationProperty(XamlHostingConfiguration.CollectionName, IsDefaultCollection = true)]
|
||||
public HandlerElementCollection Handlers
|
||||
{
|
||||
get
|
||||
{
|
||||
return (HandlerElementCollection)base[XamlHostingConfiguration.CollectionName];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,27 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Xaml.Hosting.Configuration
|
||||
{
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Runtime;
|
||||
using System.Web;
|
||||
|
||||
public sealed class XamlHostingSectionGroup : ConfigurationSectionGroup
|
||||
{
|
||||
public XamlHostingSectionGroup()
|
||||
{
|
||||
}
|
||||
|
||||
public XamlHostingSection XamlHostingSection
|
||||
{
|
||||
get
|
||||
{
|
||||
return (XamlHostingSection)this.Sections[XamlHostingConfiguration.XamlHostingConfigGroup];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,24 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.Xaml.Hosting
|
||||
{
|
||||
using System;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using System.Security;
|
||||
using System.Runtime;
|
||||
|
||||
static class HostingEnvironmentWrapper
|
||||
{
|
||||
public static IDisposable UnsafeImpersonate()
|
||||
{
|
||||
return HostingEnvironment.Impersonate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@@ -0,0 +1,17 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.Xaml.Hosting
|
||||
{
|
||||
using System.CodeDom.Compiler;
|
||||
using System.IO;
|
||||
using System.Web.Compilation;
|
||||
|
||||
internal interface IXamlBuildProviderExtension
|
||||
{
|
||||
void GenerateCode(AssemblyBuilder assemblyBuilder, Stream xamlStream, BuildProvider buildProvider);
|
||||
|
||||
Type GetGeneratedType(CompilerResults results);
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.Xaml.Hosting
|
||||
{
|
||||
using System.CodeDom.Compiler;
|
||||
using System.IO;
|
||||
using System.Web.Compilation;
|
||||
|
||||
internal interface IXamlBuildProviderExtensionFactory
|
||||
{
|
||||
IXamlBuildProviderExtension GetXamlBuildProviderExtension();
|
||||
}
|
||||
}
|
@@ -0,0 +1,168 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.Xaml.Hosting
|
||||
{
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Compilation;
|
||||
using System.Web.Hosting;
|
||||
using System.Xaml;
|
||||
using System.Xaml.Hosting.Configuration;
|
||||
using System.Xml;
|
||||
|
||||
[BuildProviderAppliesTo(BuildProviderAppliesTo.Web)]
|
||||
public class XamlBuildProvider : BuildProvider
|
||||
{
|
||||
IXamlBuildProviderExtension xamlBuildProviderExtension;
|
||||
static volatile IXamlBuildProviderExtensionFactory xamlBuildProviderExtensionFactory;
|
||||
|
||||
internal new string VirtualPath
|
||||
{
|
||||
get { return base.VirtualPath; }
|
||||
}
|
||||
|
||||
public override void GenerateCode(AssemblyBuilder assemblyBuilder)
|
||||
{
|
||||
XamlType rootXamlType = GetRootXamlType();
|
||||
|
||||
this.GetXamlBuildProviderExtension(rootXamlType);
|
||||
|
||||
if (this.xamlBuildProviderExtension != null)
|
||||
{
|
||||
using (Stream xamlStream = base.OpenStream())
|
||||
{
|
||||
this.xamlBuildProviderExtension.GenerateCode(assemblyBuilder, xamlStream, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fx.Tag.Throws(typeof(TypeLoadException), "The type resolution of the root element failed.")]
|
||||
public override Type GetGeneratedType(CompilerResults results)
|
||||
{
|
||||
if (this.xamlBuildProviderExtension != null)
|
||||
{
|
||||
Type result = this.xamlBuildProviderExtension.GetGeneratedType(results);
|
||||
if (result != null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
XamlType rootXamlType = GetRootXamlType();
|
||||
if (rootXamlType.IsUnknown)
|
||||
{
|
||||
StringBuilder typeName = new StringBuilder();
|
||||
AppendTypeName(rootXamlType, typeName);
|
||||
throw FxTrace.Exception.AsError(new TypeLoadException(SR.CouldNotResolveType(typeName)));
|
||||
}
|
||||
return rootXamlType.UnderlyingType;
|
||||
}
|
||||
catch (XamlParseException ex)
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new HttpCompileException(ex.Message, ex));
|
||||
}
|
||||
}
|
||||
|
||||
public override BuildProviderResultFlags GetResultFlags(CompilerResults results)
|
||||
{
|
||||
return BuildProviderResultFlags.ShutdownAppDomainOnChange;
|
||||
}
|
||||
|
||||
private void AppendTypeName(XamlType xamlType, StringBuilder sb)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(xamlType.PreferredXamlNamespace))
|
||||
{
|
||||
sb.Append("{");
|
||||
sb.Append(xamlType.PreferredXamlNamespace);
|
||||
sb.Append("}");
|
||||
}
|
||||
sb.Append(xamlType.Name);
|
||||
if (xamlType.IsGeneric)
|
||||
{
|
||||
sb.Append("(");
|
||||
for (int i = 0; i < xamlType.TypeArguments.Count; i++)
|
||||
{
|
||||
AppendTypeName(xamlType.TypeArguments[i], sb);
|
||||
if (i < xamlType.TypeArguments.Count - 1)
|
||||
{
|
||||
sb.Append(", ");
|
||||
}
|
||||
}
|
||||
sb.Append(")");
|
||||
}
|
||||
}
|
||||
|
||||
XamlType GetRootXamlType()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (Stream xamlStream = base.OpenStream())
|
||||
{
|
||||
XmlReader xmlReader = XmlReader.Create(xamlStream);
|
||||
XamlXmlReader xamlReader = new XamlXmlReader(xmlReader);
|
||||
|
||||
// Read to the root object
|
||||
while (xamlReader.Read())
|
||||
{
|
||||
if (xamlReader.NodeType == XamlNodeType.StartObject)
|
||||
{
|
||||
return xamlReader.Type;
|
||||
}
|
||||
}
|
||||
throw FxTrace.Exception.AsError(new HttpCompileException(SR.UnexpectedEof));
|
||||
}
|
||||
}
|
||||
catch (XamlParseException ex)
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new HttpCompileException(ex.Message, ex));
|
||||
}
|
||||
}
|
||||
|
||||
void GetXamlBuildProviderExtension(XamlType rootXamlType)
|
||||
{
|
||||
if (rootXamlType.UnderlyingType == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.GetXamlBuildProviderExtensionFactory(rootXamlType);
|
||||
|
||||
if (xamlBuildProviderExtensionFactory != null)
|
||||
{
|
||||
this.xamlBuildProviderExtension = xamlBuildProviderExtensionFactory.GetXamlBuildProviderExtension();
|
||||
}
|
||||
}
|
||||
|
||||
void GetXamlBuildProviderExtensionFactory(XamlType rootXamlType)
|
||||
{
|
||||
if (xamlBuildProviderExtensionFactory != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the HttpHandler type
|
||||
Type httpHandlerType;
|
||||
XamlHostingConfiguration.TryGetHttpHandlerType(this.VirtualPath, rootXamlType.UnderlyingType, out httpHandlerType);
|
||||
|
||||
if (httpHandlerType != null && typeof(IXamlBuildProviderExtensionFactory).IsAssignableFrom(httpHandlerType))
|
||||
{
|
||||
xamlBuildProviderExtensionFactory = (IXamlBuildProviderExtensionFactory)Activator.CreateInstance(httpHandlerType,
|
||||
BindingFlags.CreateInstance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
|
||||
null, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,315 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.Xaml.Hosting
|
||||
{
|
||||
using System;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using System.Web.Compilation;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Reflection;
|
||||
using System.Xaml.Hosting.Configuration;
|
||||
using System.Configuration;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Net;
|
||||
using System.Runtime;
|
||||
using System.Security;
|
||||
using System.Collections;
|
||||
|
||||
[SuppressMessage(FxCop.Category.Performance, FxCop.Rule.AvoidUninstantiatedInternalClasses,
|
||||
Justification = "This is instantiated by AspNet.")]
|
||||
sealed class XamlHttpHandlerFactory : IHttpHandlerFactory
|
||||
{
|
||||
public IHttpHandler GetHandler(HttpContext context, string requestType,
|
||||
string url, string pathTranslated)
|
||||
{
|
||||
//Get the "cache pointer" for the virtual path - if does not exist, create a cache pointer
|
||||
//This should happen under global lock
|
||||
PathInfo pathInfo = PathCache.EnsurePathInfo(context.Request.AppRelativeCurrentExecutionFilePath);
|
||||
return pathInfo.GetHandler(context, requestType, url, pathTranslated);
|
||||
}
|
||||
|
||||
public void ReleaseHandler(IHttpHandler httphandler)
|
||||
{
|
||||
//Check whether the handler was created by an internal factory
|
||||
if (httphandler is HandlerWrapper)
|
||||
{
|
||||
((HandlerWrapper)(httphandler)).ReleaseWrappedHandler();
|
||||
}
|
||||
}
|
||||
|
||||
static object CreateInstance(Type type)
|
||||
{
|
||||
//The handler/factory should have an empty constructor but need not be public
|
||||
return Activator.CreateInstance(type,
|
||||
BindingFlags.CreateInstance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
|
||||
null, null, null);
|
||||
}
|
||||
|
||||
static class PathCache
|
||||
{
|
||||
[Fx.Tag.Cache(
|
||||
typeof(PathInfo),
|
||||
Fx.Tag.CacheAttrition.None,
|
||||
Scope = "instance of declaring class",
|
||||
SizeLimit = "unbounded",
|
||||
Timeout = "infinite"
|
||||
)]
|
||||
static Hashtable pathCache = new Hashtable(StringComparer.OrdinalIgnoreCase);
|
||||
static object writeLock = new object();
|
||||
|
||||
public static PathInfo EnsurePathInfo(string path)
|
||||
{
|
||||
PathInfo pathInfo = (PathInfo)pathCache[path];
|
||||
if (pathInfo != null)
|
||||
{
|
||||
return pathInfo;
|
||||
}
|
||||
|
||||
lock (writeLock)
|
||||
{
|
||||
pathInfo = (PathInfo)pathCache[path];
|
||||
if (pathInfo != null)
|
||||
{
|
||||
return pathInfo;
|
||||
}
|
||||
|
||||
if (HostingEnvironment.VirtualPathProvider.FileExists(path))
|
||||
{
|
||||
pathInfo = new PathInfo();
|
||||
pathCache.Add(path, pathInfo);
|
||||
return pathInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new HttpException((int)HttpStatusCode.NotFound, SR.ResourceNotFound));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class HandlerWrapper : IHttpHandler
|
||||
{
|
||||
IHttpHandlerFactory factory;
|
||||
|
||||
IHttpHandler httpHandler;
|
||||
|
||||
private HandlerWrapper(IHttpHandler httpHandler, IHttpHandlerFactory factory)
|
||||
{
|
||||
this.httpHandler = httpHandler;
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public bool IsReusable
|
||||
{
|
||||
get { return httpHandler.IsReusable; }
|
||||
}
|
||||
|
||||
public static IHttpHandler Create(
|
||||
IHttpHandler httpHandler, IHttpHandlerFactory factory)
|
||||
{
|
||||
if (httpHandler is IHttpAsyncHandler)
|
||||
{
|
||||
return new AsyncHandlerWrapper((IHttpAsyncHandler)httpHandler, factory);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new HandlerWrapper(httpHandler, factory);
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessRequest(HttpContext context)
|
||||
{
|
||||
httpHandler.ProcessRequest(context);
|
||||
}
|
||||
|
||||
public void ReleaseWrappedHandler()
|
||||
{
|
||||
this.factory.ReleaseHandler(httpHandler);
|
||||
}
|
||||
|
||||
class AsyncHandlerWrapper : HandlerWrapper, IHttpAsyncHandler
|
||||
{
|
||||
//Storing a local copy to avoid unnecessary typecasts during begin/end
|
||||
IHttpAsyncHandler httpAsyncHandler;
|
||||
|
||||
public AsyncHandlerWrapper(IHttpAsyncHandler httpAsyncHandler, IHttpHandlerFactory factory)
|
||||
: base(httpAsyncHandler, factory)
|
||||
{
|
||||
this.httpAsyncHandler = httpAsyncHandler;
|
||||
}
|
||||
|
||||
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
|
||||
{
|
||||
return this.httpAsyncHandler.BeginProcessRequest(context, cb, extraData);
|
||||
}
|
||||
|
||||
public void EndProcessRequest(IAsyncResult result)
|
||||
{
|
||||
this.httpAsyncHandler.EndProcessRequest(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PathInfo
|
||||
{
|
||||
object cachedResult;
|
||||
Type hostedXamlType;
|
||||
object writeLock;
|
||||
|
||||
public PathInfo()
|
||||
{
|
||||
this.writeLock = new object();
|
||||
}
|
||||
|
||||
[Fx.Tag.Throws(typeof(ConfigurationErrorsException), "Invalid Configuration.")]
|
||||
public IHttpHandler GetHandler(HttpContext context, string requestType,
|
||||
string url, string pathTranslated)
|
||||
{
|
||||
if (this.cachedResult == null)
|
||||
{
|
||||
//Cache won't be available if it is invoked first time
|
||||
//Use a local "lock" specifically for this url
|
||||
lock (this.writeLock)
|
||||
{
|
||||
if (this.cachedResult == null)
|
||||
{
|
||||
return GetHandlerFirstTime(context, requestType, url, pathTranslated);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GetHandlerSubSequent(context, requestType, url, pathTranslated);
|
||||
}
|
||||
|
||||
[Fx.Tag.SecurityNote(Critical = "Uses SecurityCritical method UnsafeImpersonate to establish the impersonation context",
|
||||
Safe = "Does not leak anything, does not let caller influence impersonation.")]
|
||||
// Why this triple try blocks instead of using "using" statement:
|
||||
// 1. "using" will do the impersonation prior to entering the try,
|
||||
// which leaves an opertunity to Thread.Abort this thread and get it to exit the method still impersonated.
|
||||
// 2. put the assignment of unsafeImpersonate in a finally block
|
||||
// in order to prevent Threat.Abort after impersonation but before the assignment.
|
||||
// 3. the finally of a "using" doesn't run until exception filters higher up the stack have executed.
|
||||
// they will do so in the impersonated context if an exception is thrown inside the try.
|
||||
// In sumary, this should prevent the thread from existing this method well still impersonated.
|
||||
Type GetCompiledCustomString(string normalizedVirtualPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
IDisposable unsafeImpersonate = null;
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
unsafeImpersonate = HostingEnvironmentWrapper.UnsafeImpersonate();
|
||||
}
|
||||
return BuildManager.GetCompiledType(normalizedVirtualPath);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (null != unsafeImpersonate)
|
||||
{
|
||||
unsafeImpersonate.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//This function is invoked the first time a request is made to XAMLx file
|
||||
//It caches url as key and one of the
|
||||
//following 4 as value -> "Handler/Factory/HandlerCLRType/Exception"
|
||||
IHttpHandler GetHandlerFirstTime(HttpContext context, string requestType,
|
||||
string url, string pathTranslated)
|
||||
{
|
||||
Type httpHandlerType;
|
||||
ConfigurationErrorsException configException;
|
||||
|
||||
//GetCompiledType is costly - invoke it just once.
|
||||
//This null check is required for "error after GetCompiledType on first attempt" cases only
|
||||
if (this.hostedXamlType == null)
|
||||
{
|
||||
this.hostedXamlType = GetCompiledCustomString(context.Request.AppRelativeCurrentExecutionFilePath);
|
||||
}
|
||||
|
||||
if (XamlHostingConfiguration.TryGetHttpHandlerType(url, this.hostedXamlType, out httpHandlerType))
|
||||
{
|
||||
if (TD.HttpHandlerPickedForUrlIsEnabled())
|
||||
{
|
||||
TD.HttpHandlerPickedForUrl(url, hostedXamlType.FullName, httpHandlerType.FullName);
|
||||
}
|
||||
if (typeof(IHttpHandler).IsAssignableFrom(httpHandlerType))
|
||||
{
|
||||
IHttpHandler handler = (IHttpHandler)CreateInstance(httpHandlerType);
|
||||
if (handler.IsReusable)
|
||||
{
|
||||
this.cachedResult = handler;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.cachedResult = httpHandlerType;
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
else if (typeof(IHttpHandlerFactory).IsAssignableFrom(httpHandlerType))
|
||||
{
|
||||
IHttpHandlerFactory factory = (IHttpHandlerFactory)CreateInstance(httpHandlerType);
|
||||
this.cachedResult = factory;
|
||||
IHttpHandler handler = factory.GetHandler(context, requestType, url, pathTranslated);
|
||||
return HandlerWrapper.Create(handler, factory);
|
||||
}
|
||||
else
|
||||
{
|
||||
configException =
|
||||
new ConfigurationErrorsException(SR.NotHttpHandlerType(url, this.hostedXamlType, httpHandlerType.FullName));
|
||||
this.cachedResult = configException;
|
||||
throw FxTrace.Exception.AsError(configException);
|
||||
}
|
||||
}
|
||||
configException =
|
||||
new ConfigurationErrorsException(SR.HttpHandlerForXamlTypeNotFound(url, this.hostedXamlType, XamlHostingConfiguration.XamlHostingSection));
|
||||
this.cachedResult = configException;
|
||||
throw FxTrace.Exception.AsError(configException);
|
||||
}
|
||||
|
||||
//This function retrievs the cached object and uses it to get handler or exception
|
||||
IHttpHandler GetHandlerSubSequent(HttpContext context, string requestType,
|
||||
string url, string pathTranslated)
|
||||
{
|
||||
if (this.cachedResult is IHttpHandler)
|
||||
{
|
||||
return ((IHttpHandler)this.cachedResult);
|
||||
}
|
||||
else if (this.cachedResult is IHttpHandlerFactory)
|
||||
{
|
||||
IHttpHandlerFactory factory = ((IHttpHandlerFactory)this.cachedResult);
|
||||
IHttpHandler handler = factory.GetHandler(context, requestType, url, pathTranslated);
|
||||
return HandlerWrapper.Create(handler, factory);
|
||||
}
|
||||
else if (this.cachedResult is Type)
|
||||
{
|
||||
return (IHttpHandler)CreateInstance((Type)this.cachedResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw FxTrace.Exception.AsError((ConfigurationErrorsException)this.cachedResult);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user