1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Activation
{
using System.Diagnostics;
using System.Runtime;
using System.Security;
using System.ServiceModel;
using System.Web;
class ServiceHttpModule : IHttpModule
{
[Fx.Tag.SecurityNote(Critical = "Holds pointer to BeginProcessRequest which is SecurityCritical." +
"This callback is called outside the PermitOnly context.")]
[SecurityCritical]
static BeginEventHandler beginEventHandler;
static CompletedAsyncResult cachedAsyncResult = new CompletedAsyncResult(null, null);
[Fx.Tag.SecurityNote(Critical = "This callback is called outside the PermitOnly context.")]
[SecurityCritical]
static EndEventHandler endEventHandler;
static bool disabled;
[Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - called outside PermitOnly context.")]
public void Dispose()
{
}
[Fx.Tag.SecurityNote(Critical = "Entry-point from ASP.NET, accesses begin/bndProcessRequest which are SecurityCritical.")]
[SecurityCritical]
public void Init(HttpApplication context)
{
if (ServiceHttpModule.beginEventHandler == null)
{
ServiceHttpModule.beginEventHandler = new BeginEventHandler(BeginProcessRequest);
}
if (ServiceHttpModule.endEventHandler == null)
{
ServiceHttpModule.endEventHandler = new EndEventHandler(EndProcessRequest);
}
context.AddOnPostAuthenticateRequestAsync(
ServiceHttpModule.beginEventHandler,
ServiceHttpModule.endEventHandler);
}
[Fx.Tag.SecurityNote(Critical = "Entry-point from asp.net, called outside PermitOnly context. ASP.NET calls are critical." +
"HostedHttpRequestAsyncResult..ctor is critical because it captures HostedImpersonationContext (and makes it available later) " +
"so caller must ensure that this is called in the right place.")]
[SecurityCritical]
static public IAsyncResult BeginProcessRequest(object sender, EventArgs e, AsyncCallback cb, object extraData)
{
if (ServiceHttpModule.disabled)
{
return GetCompletedAsyncResult(cb, extraData);
}
try
{
ServiceHostingEnvironment.SafeEnsureInitialized();
}
catch (SecurityException exception)
{
ServiceHttpModule.disabled = true;
DiagnosticUtility.TraceHandledException(exception, TraceEventType.Warning);
// If requesting a .svc file, the HttpHandler will try to handle it. It will call
// SafeEnsureInitialized() again, which will fail with the same exception (it is
// idempotent on failure). This is the correct behavior.
return GetCompletedAsyncResult(cb, extraData);
}
HttpApplication application = (HttpApplication) sender;
// Check to see whether the extension is supported.
string extension = application.Request.CurrentExecutionFilePathExtension;
if (string.IsNullOrEmpty(extension))
{
return GetCompletedAsyncResult(cb, extraData);
}
ServiceHostingEnvironment.ServiceType serviceType = ServiceHostingEnvironment.GetServiceType(extension);
// do extension check first so that we do not need to do it in aspnetrouting/configurationbasedactivation
if (serviceType == ServiceHostingEnvironment.ServiceType.Unknown)
{
return GetCompletedAsyncResult(cb, extraData);
}
// check for AspNetcompat
if (ServiceHostingEnvironment.AspNetCompatibilityEnabled)
{
// remap httphandler for xamlx in CBA, since there is No physical file and
// the xamlx httphandlerfactory will do file exist checking
if (serviceType == ServiceHostingEnvironment.ServiceType.Workflow && ServiceHostingEnvironment.IsConfigurationBasedService(application))
{
IHttpHandler cbaHandler = new ServiceHttpHandlerFactory().GetHandler(
application.Context, application.Request.RequestType,
application.Request.RawUrl.ToString(), application.Request.PhysicalApplicationPath);
application.Context.RemapHandler(cbaHandler);
}
return GetCompletedAsyncResult(cb, extraData);
}
if (serviceType == ServiceHostingEnvironment.ServiceType.WCF)
{
return new HostedHttpRequestAsyncResult(application, false, false, cb, extraData);
}
if (serviceType == ServiceHostingEnvironment.ServiceType.Workflow)
{
return new HostedHttpRequestAsyncResult(application, false, true, cb, extraData);
}
return GetCompletedAsyncResult(cb, extraData);
}
private static CompletedAsyncResult GetCompletedAsyncResult(AsyncCallback cb, object state)
{
return (cb == null) ? cachedAsyncResult : new CompletedAsyncResult(cb, state);
}
[Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - called outside PermitOnly context.")]
static public void EndProcessRequest(IAsyncResult ar)
{
//No need to call CompletedAsyncResult.End as the asyncResult has already completed.
if (ar is HostedHttpRequestAsyncResult)
{
HostedHttpRequestAsyncResult.End(ar);
}
}
}
}
|