HostedHttpRequestAsyncResult.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / System.ServiceModel.Activation / System / ServiceModel / Activation / HostedHttpRequestAsyncResult.cs / 1305376 / HostedHttpRequestAsyncResult.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------
namespace System.ServiceModel.Activation
{ 
    using System.Diagnostics;
    using System.IO; 
    using System.Net; 
    using System.Runtime;
    using System.Runtime.Diagnostics; 
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using System.Security;
    using System.Security.Authentication.ExtendedProtection; 
    using System.Security.Cryptography.X509Certificates;
    using System.Security.Permissions; 
    using System.Security.Principal; 
    using System.ServiceModel;
    using System.ServiceModel.Channels; 
    using System.ServiceModel.Activation.Diagnostics;
    using System.Threading;
    using System.Web;
    using System.Web.Routing; 
    using TD2 = System.ServiceModel.Diagnostics.Application.TD;
 
    class HostedHttpRequestAsyncResult : AsyncResult, HttpChannelListener.IHttpAuthenticationContext 
    {
        [Fx.Tag.SecurityNote(Critical = "Stores the securitycritical callback values, we need to protect these values")] 
        [SecurityCritical]
        static WindowsIdentity anonymousIdentity;
        [SecurityCritical]
        static Action waitOnBeginRequest; 
        [SecurityCritical]
        static Action waitOnBeginRequestWithFlow; 
        [SecurityCritical] 
        static ContextCallback contextOnBeginRequest;
        [SecurityCritical] 
        static AsyncCallback processRequestCompleteCallback;


        [ThreadStatic] 
        static AutoResetEvent waitObject;
 
        static Nullable iisSupportsExtendedProtection; 

        [Fx.Tag.SecurityNote(Critical = "Keeps track of impersonated user, caller must use with care")] 
        [SecurityCritical]
        HostedImpersonationContext impersonationContext;

        [Fx.Tag.SecurityNote(Critical = "Keeps track of thread static data (HttpContext, CurrentCulture, CurrentUICulture) that is used for AspNetCompatibility mode, caller must use with care")] 
        [SecurityCritical]
        HostedThreadData hostedThreadData; 
 
        [Fx.Tag.SecurityNote(Critical =
            "This field is used to manipulate request/responses using APIs protected by LinkDemand." + 
            "It is critical because we use it to determine whether we believe we're being hosted in ASP.NET or not." +
            "The field is set in the constructor of this class and we deem it safe because:" +
            "    1) all paths that lead to the .ctor are SecurityCritical and" +
            "    2) those paths have called ServiceHostingEnvironment.EnsureInitialized (which is also critical)" + 
            "So if the field is non-null, it's safe to say that we're hosted in ASP.NET, hence all the helper methods in this class that touch this field can be SecurityTreatAsSafe")]
        [SecurityCritical] 
        HttpApplication context; 

        int state; 

        [Fx.Tag.SecurityNote(Critical = "Determines whether to set the HttpContext on the outgoing thread.")]
        [SecurityCritical]
        bool flowContext; 
        bool ensureWFService;
        string configurationBasedServiceVirtualPath; 
 
        [Fx.Tag.SecurityNote(Critical = "Captures HostedImpersonationContext which must be done in the right place, and calls unsafe" +
        "ScheduleCallbackLowPriNoFlow and ScriptTimeout.  Called outside of user security context.")] 
        [SecurityCritical]
        public HostedHttpRequestAsyncResult(HttpApplication context, bool flowContext, bool ensureWFService, AsyncCallback callback, object state) :
            this(context, null, flowContext, ensureWFService, callback, state)
        { 
        }
 
        [Fx.Tag.SecurityNote(Critical = "Captures HostedImpersonationContext which must be done in the right place, and calls unsafe" + 
            "ScheduleCallbackLowPriNoFlow and ScriptTimeout.  Called outside of user security context.")]
        [SecurityCritical] 
        public HostedHttpRequestAsyncResult(HttpApplication context, string aspNetRouteServiceVirtualPath, bool flowContext, bool ensureWFService, AsyncCallback callback, object state) :
            base(callback, state)
        {
            if (context == null) 
            {
                throw FxTrace.Exception.ArgumentNull("context"); 
            } 
            this.context = context;
            this.flowContext = flowContext; 
            if (ensureWFService)
            {
                // check for CBA scenario. if true, service should be handled by WCF instead of WF,
                // set this.ensureWFservice to false 
                if (ServiceHostingEnvironment.IsConfigurationBasedService(context, out this.configurationBasedServiceVirtualPath))
                { 
                    this.ensureWFService = false; 
                }
                else 
                {
                    this.ensureWFService = true;
                }
            } 

            if (!string.IsNullOrEmpty(aspNetRouteServiceVirtualPath)) 
            { 
                // aspnet routing can hijack CBA request as we append {*pathInfo} to urlpattern and there is no real file for CBA
                // check for CBA scenario. if the request is hijacked. i.e., 
                // 1) route maps to a virtual directory:
                // aspNetRouteServiceVirtualPath <> context.Request.AppRelativeCurrentExecutionFilePath == configurationBasedServiceVirtualPath
                // if RouteExistingFiles <> true, set aspnetRouteServiceVirtualPath to null so that the request will be treated as CBA
                // if RouteExistingFiles == true, this hijack is by-design, do nothing 
                // 2) route maps to a CBA entry:
                // aspNetRouteServiceVirtualPath == context.Request.AppRelativeCurrentExecutionFilePath == configurationBasedServiceVirtualPath 
                // we will use RouteExistingFiles to decide which service should be activated. We do it in ServiceHostingEnviroment.HostingManager, 
                // as we cannot pass this info to the latter.
                if (!RouteTable.Routes.RouteExistingFiles && 
                    ServiceHostingEnvironment.IsConfigurationBasedService(context, out this.configurationBasedServiceVirtualPath))
                {
                    this.AspNetRouteServiceVirtualPath = null;
                } 
                else
                { 
                    this.AspNetRouteServiceVirtualPath = aspNetRouteServiceVirtualPath; 
                }
            } 

            // If this is a DEBUG request, complete right away and let ASP.NET handle it.
            string method = context.Request.HttpMethod ?? "";
            char firstMethodChar = method.Length == 5 ? method[0] : '\0'; 
            if ((firstMethodChar == 'd' || firstMethodChar == 'D') &&
                string.Compare(method, "DEBUG", StringComparison.OrdinalIgnoreCase) == 0) 
            { 
                if (DiagnosticUtility.ShouldTraceVerbose)
                { 
                    TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.WebHostDebugRequest, SR.TraceCodeWebHostDebugRequest, this);
                }

                this.state = State.Completed; 
                Complete(true, null);
                return; 
            } 

            this.impersonationContext = new HostedImpersonationContext(); 

            if (flowContext)
            {
                if (ServiceHostingEnvironment.AspNetCompatibilityEnabled) 
                {
                    // Capture HttpContext/culture context if necessary.  Can be used later by HostedHttpInput to re-apply 
                    // the culture during dispatch.  Also flowed here. 
                    hostedThreadData = new HostedThreadData();
                } 
            }

            // Set this up before calling IncrementRequestCount so if it fails, we don't leak a count.
            Action iotsCallback = (AspNetPartialTrustHelpers.NeedPartialTrustInvoke || flowContext) ? 
                WaitOnBeginRequestWithFlow : WaitOnBeginRequest;
 
            // Tell ASPNET to by-pass all the other events so no other http modules will 
            // be invoked, Indigo basically takes over the request completely. This should
            // only be called in non-AspNetCompatibilityEnabled mode. 
            if (!ServiceHostingEnvironment.AspNetCompatibilityEnabled && !this.ensureWFService)
            {
                context.CompleteRequest();
            } 

            // Prevent ASP.NET from generating thread aborts in relation to this request. 
            context.Server.ScriptTimeout = int.MaxValue; 

            ServiceHostingEnvironment.IncrementRequestCount(); 

            IOThreadScheduler.ScheduleCallbackLowPriNoFlow(iotsCallback, this);
        }
 
        public static WindowsIdentity AnonymousIdentity
        { 
            [Fx.Tag.SecurityNote(Critical = "Access the value of corresponding static field and prevent someone from changing its value")] 
            [SecuritySafeCritical]
            get 
            {
                if (anonymousIdentity == null)
                {
                    anonymousIdentity = WindowsIdentity.GetAnonymous(); 
                }
                return anonymousIdentity; 
            } 
        }
 
        public static Action WaitOnBeginRequest
        {
            [Fx.Tag.SecurityNote(Critical = "Access the value of corresponding static field and prevent someone from changing its value")]
            [SecuritySafeCritical] 
            get
            { 
                if (waitOnBeginRequest == null) 
                {
                    waitOnBeginRequest = new Action(OnBeginRequest); 
                }
                return waitOnBeginRequest;
            }
        } 

        public static Action WaitOnBeginRequestWithFlow 
        { 
            [Fx.Tag.SecurityNote(Critical = "Access the value of corresponding static field and prevent someone from changing its value")]
            [SecuritySafeCritical] 
            get
            {
                if (waitOnBeginRequestWithFlow == null)
                { 
                    waitOnBeginRequestWithFlow = new Action(OnBeginRequestWithFlow);
                } 
                return waitOnBeginRequestWithFlow; 
            }
        } 

        public static ContextCallback ContextOnBeginRequest
        {
            [Fx.Tag.SecurityNote(Critical = "Access the value of corresponding static field and prevent someone from changing its value")] 
            [SecuritySafeCritical]
            get 
            { 
                if (contextOnBeginRequest == null)
                { 
                    contextOnBeginRequest = new ContextCallback(OnBeginRequest);
                }
                return contextOnBeginRequest;
            } 
        }
 
        public static AsyncCallback ProcessRequestCompleteCallback 
        {
            [Fx.Tag.SecurityNote(Critical = "Access the value of corresponding static field and prevent someone from changing its value")] 
            [SecuritySafeCritical]
            get
            {
                if (processRequestCompleteCallback == null) 
                {
                    processRequestCompleteCallback = Fx.ThunkCallback(new AsyncCallback(ProcessRequestComplete)); 
                } 
                return processRequestCompleteCallback;
            } 
        }

        public bool IISSupportsExtendedProtection
        { 
            get
            { 
                if (HostedHttpRequestAsyncResult.iisSupportsExtendedProtection == null) 
                {
                    HostedHttpRequestAsyncResult.iisSupportsExtendedProtection = this.IISSupportsExtendedProtectionInternal(); 
                }
                return HostedHttpRequestAsyncResult.iisSupportsExtendedProtection.Value;
            }
        } 

        [Fx.Tag.SecurityNote(Critical = "Touches critical field context.", Safe = "Does not leak control or data, no potential for harm.")] 
        [SecuritySafeCritical] 
        [MethodImpl(MethodImplOptions.NoInlining)]
        [PermissionSetAttribute(SecurityAction.Assert, Unrestricted = true)] 
        private bool IISSupportsExtendedProtectionInternal()
        {
            DiagnosticUtility.DebugAssert(ExtendedProtectionPolicy.OSSupportsExtendedProtection, "OS must support ExtendedProtection");
 
            try
            { 
                ChannelBinding cbt = this.context.Request.HttpChannelBinding; 
                return true;
            } 
            catch (PlatformNotSupportedException)
            {
                // contract with Asp.Net is that they will always throw a PlatformNotSupportedException if IIS is not patched for CBT yet
                return false; 
            }
            catch (COMException) 
            { 
                // If IIS is patched for CBT and an error occurs when trying to retrieve the token a COMException is thrown. Even in this
                // case we know that IIS is patched for CBT. 
                return true;
            }
        }
 

        [Fx.Tag.SecurityNote(Critical = "Captures HostedImpersonationContext which must be done in the right place, and calls unsafe" + 
            "ScheduleCallbackLowPriNoFlow and ScriptTimeout.  Called outside of user security context." + 
            "Callers of this function must call ServiceHostingEnvironment.EnsureInitialized")]
        [SecurityCritical] 
        public static void ExecuteSynchronous(HttpApplication context, bool flowContext, bool ensureWFService)
        {
            ExecuteSynchronous(context, null, flowContext, ensureWFService);
        } 

        [Fx.Tag.SecurityNote(Critical = "Captures HostedImpersonationContext which must be done in the right place, and calls unsafe" + 
            "ScheduleCallbackLowPriNoFlow and ScriptTimeout.  Called outside of user security context." + 
            "Callers of this function must call ServiceHostingEnvironment.EnsureInitialized")]
        [SecurityCritical] 
        public static void ExecuteSynchronous(HttpApplication context, string routeServiceVirtualPath, bool flowContext, bool ensureWFService)
        {
            AutoResetEvent wait = HostedHttpRequestAsyncResult.waitObject;
            if (wait == null) 
            {
                wait = new AutoResetEvent(false); 
                HostedHttpRequestAsyncResult.waitObject = wait; 
            }
 
            HostedHttpRequestAsyncResult result;
            try
            {
                result = new HostedHttpRequestAsyncResult(context, routeServiceVirtualPath, flowContext, ensureWFService, ProcessRequestCompleteCallback, wait); 
                if (!result.CompletedSynchronously)
                { 
                    wait.WaitOne(); 
                }
                wait = null; 
            }
            finally
            {
                if (wait != null) 
                {
                    // Not sure of the state anymore. 
                    HostedHttpRequestAsyncResult.waitObject = null; 
                    wait.Close();
                } 
            }

            HostedHttpRequestAsyncResult.End(result);
        } 

        [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Can be called outside of a user context.")] 
        static void ProcessRequestComplete(IAsyncResult result) 
        {
            if (!result.CompletedSynchronously) 
            {
                try
                {
                    ((AutoResetEvent)result.AsyncState).Set(); 
                }
                catch (ObjectDisposedException exception) 
                { 
                    if (DiagnosticUtility.ShouldTraceWarning)
                    { 
                        DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Warning);
                    }
                }
            } 
        }
 
        [Fx.Tag.SecurityNote(Critical = "Can be called outside of user context, accesses hostedThreadData.", 
            Safe = "Uses hostedThreadData to set HttpContext.Current, cultures to the one attached to this async-result instance.")]
        [SecuritySafeCritical] 
        static void OnBeginRequestWithFlow(object state)
        {
            HostedHttpRequestAsyncResult self = (HostedHttpRequestAsyncResult)state;
 
            IDisposable hostedThreadContext = null;
            try 
            { 
                if (self.flowContext)
                { 
                    // In AspCompat case, these are the three things that need to be flowed.  See HostedHttpInput.
                    if (self.hostedThreadData != null)
                    {
                        hostedThreadContext = self.hostedThreadData.CreateContext(); 
                    }
                } 
 
                // In full-trust, this simply calls the delegate.
                AspNetPartialTrustHelpers.PartialTrustInvoke(ContextOnBeginRequest, self); 
            }
            finally
            {
                if (hostedThreadContext != null) 
                {
                    hostedThreadContext.Dispose(); 
                } 
            }
        } 

        static void OnBeginRequest(object state)
        {
            HostedHttpRequestAsyncResult self = (HostedHttpRequestAsyncResult)state; 

            Exception completionException = null; 
            try 
            {
                self.BeginRequest(); 
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e)) 
                {
                    throw; 
                } 

                completionException = e; 
            }

            if (completionException != null)
            { 
                self.CompleteOperation(completionException);
            } 
        } 

        void BeginRequest() 
        {
            try
            {
                HandleRequest(); 
            }
            catch (EndpointNotFoundException exception) 
            { 
                if (string.Compare(GetHttpMethod(), "GET", StringComparison.OrdinalIgnoreCase) == 0)
                { 
                    // Wrap the exception into HttpException.
                    throw FxTrace.Exception.AsError(new HttpException((int)HttpStatusCode.NotFound, exception.Message, exception));
                }
 
                SetStatusCode((int)HttpStatusCode.NotFound);
                CompleteOperation(null); 
            } 
            catch (ServiceActivationException exception)
            { 
                if (string.Compare(GetHttpMethod(), "GET", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    if (exception.InnerException is HttpException)
                    { 
                        throw exception.InnerException;
                    } 
                    else 
                    {
                        throw; 
                    }
                }

                SetStatusCode((int)HttpStatusCode.InternalServerError); 
                SetStatusDescription(
                    HttpChannelUtilities.StatusDescriptionStrings.HttpStatusServiceActivationException); 
                CompleteOperation(null); 
            }
            finally 
            {
                ReleaseImpersonation();
            }
        } 

        public WindowsIdentity LogonUserIdentity 
        { 
            get
            { 
                if (this.Application.User.Identity is WindowsIdentity)
                {
                    return (WindowsIdentity)this.Application.User.Identity;
                } 
                return AnonymousIdentity;
            } 
        } 

        WindowsIdentity HttpChannelListener.IHttpAuthenticationContext.LogonUserIdentity 
        {
            get
            {
                return this.LogonUserIdentity; 
            }
        } 
 
        public HostedImpersonationContext ImpersonationContext
        { 
            [Fx.Tag.SecurityNote(Critical = "Keeps track of impersonated user, caller must use with care.",
                Safe = "Safe for Get, individual members of HostedImpersonationContext are protected.")]
            [SecuritySafeCritical]
            get 
            {
                return this.impersonationContext; 
            } 
        }
 
        public HostedThreadData HostedThreadData
        {
            [Fx.Tag.SecurityNote(Critical = "Keeps track of impersonated user, caller must use with care.",
                Safe = "Safe for Get, individual members of HostedThreadData are protected.")] 
            [SecuritySafeCritical]
            get 
            { 
                return this.hostedThreadData;
            } 
        }

        public Uri OriginalRequestUri
        { 
            get;
            private set; 
 
        }
 
        public Uri RequestUri
        {
            get;
            private set; 
        }
 
        public HttpApplication Application 
        {
            [Fx.Tag.SecurityNote(Critical = "Touches critical field context.", Safe = "Does not leak control or data, no potential for harm.")] 
            [SecuritySafeCritical]
            get
            {
                return this.context; 
            }
        } 
 
        public string AspNetRouteServiceVirtualPath
        { 
            get;
            private set;
        }
 
        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.", Safe = "Does not leak control or data, no potential for harm.")]
        [SecuritySafeCritical] 
        public Stream GetInputStream() 
        {
            try 
            {
                return this.context.Request.InputStream;
            }
            catch (HttpException hostedException) 
            {
                throw FxTrace.Exception.AsError(new CommunicationException(hostedException.Message, hostedException)); 
            } 
        }
 
        public void OnReplySent()
        {
            CompleteOperation(null);
        } 

        void CompleteOperation(Exception exception) 
        { 
            if (this.state == State.Running &&
                Interlocked.CompareExchange(ref this.state, State.Completed, State.Running) == State.Running) 
            {
                Complete(false, exception);
                ServiceHostingEnvironment.DecrementRequestCount();
            } 
        }
 
        public void Abort() 
        {
            if (this.state == State.Running && 
                Interlocked.CompareExchange(ref this.state, State.Aborted, State.Running) == State.Running)
            {
                // Closes the socket connection to the client
                Application.Response.Close(); 

                Complete(false, null); 
                ServiceHostingEnvironment.DecrementRequestCount(); 
            }
        } 

        [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Can be called outside of a user context.")]
        public static void End(IAsyncResult result)
        { 
            try
            { 
                AsyncResult.End(result); 
            }
            catch (Exception exception) 
            {
                if (!Fx.IsFatal(exception))
                {
                    // Log the exception. 
                    DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error, System.ServiceModel.Diagnostics.EventLogCategory.WebHost, System.ServiceModel.Diagnostics.EventLogEventId.WebHostFailedToProcessRequest,
                      TraceUtility.CreateSourceString(result), 
                      exception == null ? string.Empty : exception.ToString()); 
                }
                throw; 
            }
        }

        X509Certificate2 HttpChannelListener.IHttpAuthenticationContext.GetClientCertificate(out bool isValidCertificate) 
        {
            HttpClientCertificate certificateInfo = this.Application.Request.ClientCertificate; 
            isValidCertificate = certificateInfo.IsValid; 
            if (certificateInfo.IsPresent)
            { 
                return new X509Certificate2(certificateInfo.Certificate);
            }
            else
            { 
                return null;
            } 
        } 

        TraceRecord HttpChannelListener.IHttpAuthenticationContext.CreateTraceRecord() 
        {
            return new System.ServiceModel.Diagnostics.HttpRequestTraceRecord(this.Application.Request);
        }
 
        void HandleRequest()
        { 
            this.OriginalRequestUri = GetUrl(); 
            string relativeVirtualPath;
            if (!string.IsNullOrEmpty(this.AspNetRouteServiceVirtualPath)) 
            {
                relativeVirtualPath = this.AspNetRouteServiceVirtualPath;
            }
            else if (!string.IsNullOrEmpty(this.configurationBasedServiceVirtualPath)) 
            {
                relativeVirtualPath = this.configurationBasedServiceVirtualPath; 
 
            }
            else 
            {
                relativeVirtualPath = GetAppRelativeCurrentExecutionFilePath();
            }
 
            if (ensureWFService)
            { 
                bool bypass = false; 
                try
                { 
                    if (!ServiceHostingEnvironment.EnsureWorkflowService(relativeVirtualPath))
                    {
                        CompleteOperation(null);
                        bypass = true; 
                        return;
                    } 
                } 
                finally
                { 
                    if (!bypass)
                    {
                        CompleteRequest();
                    } 
                }
            } 
 
            // Support for Cassini.
            if (ServiceHostingEnvironment.IsSimpleApplicationHost) 
            {
                HostedTransportConfigurationManager.EnsureInitializedForSimpleApplicationHost(this);
            }
 
            HttpHostedTransportConfiguration transportConfiguration = HostedTransportConfigurationManager.GetConfiguration(this.OriginalRequestUri.Scheme)
                as HttpHostedTransportConfiguration; 
            HostedHttpTransportManager transportManager = null; 

            // There must be a transport binding that matches the request. 
            if (transportConfiguration != null)
            {
                transportManager = transportConfiguration.GetHttpTransportManager(this.OriginalRequestUri);
            } 

            if (transportManager == null) 
            { 
                InvalidOperationException invalidOpException = new InvalidOperationException(SR.Hosting_TransportBindingNotFound(OriginalRequestUri.ToString()));
 
                ServiceActivationException activationException = new ServiceActivationException(invalidOpException.Message, invalidOpException);

                LogServiceActivationException(activationException);
 
                throw FxTrace.Exception.AsError(activationException);
            } 
 
            this.RequestUri = new Uri(transportManager.ListenUri, this.OriginalRequestUri.PathAndQuery);
            Fx.Assert( 
                object.ReferenceEquals(this.RequestUri.Scheme, Uri.UriSchemeHttp) || object.ReferenceEquals(this.RequestUri.Scheme, Uri.UriSchemeHttps),
                "Scheme must be Http or Https.");

            ServiceHostingEnvironment.EnsureServiceAvailableFast(relativeVirtualPath); 

            transportManager.HttpContextReceived(this); 
        } 

        [Fx.Tag.SecurityNote(Critical = "Calls into an unsafe UnsafeLogEvent method", 
            Safe = "Event identities cannot be spoofed as they are constants determined inside the method")]
        [SecuritySafeCritical]
        void LogServiceActivationException(ServiceActivationException activationException)
        { 
            if (TD2.ServiceExceptionIsEnabled())
            { 
                TD2.ServiceException(activationException.ToString(), typeof(ServiceActivationException).FullName); 
            }
            DiagnosticUtility.UnsafeEventLog.UnsafeLogEvent(TraceEventType.Error, System.ServiceModel.Diagnostics.EventLogCategory.WebHost, System.ServiceModel.Diagnostics.EventLogEventId.WebHostFailedToProcessRequest, true, 
                    TraceUtility.CreateSourceString(this), activationException.ToString());
        }

        [Fx.Tag.SecurityNote(Critical = "manipulates impersonation object", 
            Safe = "Releasing the SafeHandle early could only cause a future impersonation attempt to fail. We have to handle impersonation failures well already.")]
        [SecuritySafeCritical] 
        void ReleaseImpersonation() 
        {
            if (this.impersonationContext != null) 
            {
                this.impersonationContext.Release();
            }
        } 

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects, changes properties of the HTTP response.", 
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")] 
        [SecuritySafeCritical]
        internal void SetContentType(string contentType) 
        {
            this.context.Response.ContentType = contentType;
        }
 
        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects, completes the request.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")] 
        [SecuritySafeCritical] 
        internal void CompleteRequest()
        { 
            this.context.CompleteRequest();
        }

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects, changes properties of the HTTP response.", 
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
        [SecuritySafeCritical] 
        internal void SetTransferModeToStreaming() 
        {
            this.context.Response.BufferOutput = false; 
        }

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects, changes properties of the HTTP response.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")] 
        [SecuritySafeCritical]
        internal void AppendHeader(string name, string value) 
        { 
            this.context.Response.AppendHeader(name, value);
        } 

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects, changes properties of the HTTP response.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
        [SecuritySafeCritical] 
        internal void SetStatusCode(int statusCode)
        { 
            this.context.Response.TrySkipIisCustomErrors = true; 
            this.context.Response.StatusCode = statusCode;
        } 

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects, changes properties of the HTTP response.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
        [SecuritySafeCritical] 
        internal void SetStatusDescription(string statusDescription)
        { 
            this.context.Response.StatusDescription = statusDescription; 
        }
 
        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects, changes properties of the HTTP response.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
        [SecuritySafeCritical]
        internal void SetConnectionClose() 
        {
            this.context.Response.AppendHeader("Connection", "close"); 
        } 

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.", 
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
        [SecuritySafeCritical]
        internal byte[] GetPrereadBuffer(ref int contentLength)
        { 
            byte[] preReadBuffer = new byte[1];
            if (this.GetInputStream().Read(preReadBuffer, 0, 1) > 0) 
            { 
                contentLength = -1;
                return preReadBuffer; 
            }
            return null;
        }
 
        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")] 
        [SecuritySafeCritical] 
        internal Stream GetOutputStream()
        { 
            return this.context.Response.OutputStream;
        }

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.", 
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
        [SecuritySafeCritical] 
        internal string GetHttpMethod() 
        {
            return this.context.Request.HttpMethod; 
        }

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")] 
        [SecuritySafeCritical]
        internal string GetContentType() 
        { 
            const string ContentTypeHeaderName = "Content-Type";
            return this.context.Request.Headers[ContentTypeHeaderName]; 
        }

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")] 
        [SecuritySafeCritical]
        internal string GetContentTypeFast() 
        { 
            return this.context.Request.ContentType;
        } 

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
        [SecuritySafeCritical] 
        internal int GetContentLength()
        { 
            return this.context.Request.ContentLength; 
        }
 
        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
        [SecuritySafeCritical]
        internal string GetSoapAction() 
        {
            const string SoapActionHeaderName = "SOAPAction"; 
            return this.context.Request.Headers[SoapActionHeaderName]; 
        }
 
        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
        [SecuritySafeCritical]
        internal ChannelBinding GetChannelBinding() 
        {
            if (!this.IISSupportsExtendedProtection) 
            { 
                return null;
            } 

            return this.context.Request.HttpChannelBinding;
        }
 

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.", 
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")] 
        [SecuritySafeCritical]
        string GetAppRelativeCurrentExecutionFilePath() 
        {
            return this.context.Request.AppRelativeCurrentExecutionFilePath;
        }
 
        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")] 
        [SecuritySafeCritical] 
        Uri GetUrl()
        { 
            return this.context.Request.Url;
        }

        static class State 
        {
            internal const int Running = 0; 
            internal const int Completed = 1; 
            internal const int Aborted = 2;
        } 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------
namespace System.ServiceModel.Activation
{ 
    using System.Diagnostics;
    using System.IO; 
    using System.Net; 
    using System.Runtime;
    using System.Runtime.Diagnostics; 
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using System.Security;
    using System.Security.Authentication.ExtendedProtection; 
    using System.Security.Cryptography.X509Certificates;
    using System.Security.Permissions; 
    using System.Security.Principal; 
    using System.ServiceModel;
    using System.ServiceModel.Channels; 
    using System.ServiceModel.Activation.Diagnostics;
    using System.Threading;
    using System.Web;
    using System.Web.Routing; 
    using TD2 = System.ServiceModel.Diagnostics.Application.TD;
 
    class HostedHttpRequestAsyncResult : AsyncResult, HttpChannelListener.IHttpAuthenticationContext 
    {
        [Fx.Tag.SecurityNote(Critical = "Stores the securitycritical callback values, we need to protect these values")] 
        [SecurityCritical]
        static WindowsIdentity anonymousIdentity;
        [SecurityCritical]
        static Action waitOnBeginRequest; 
        [SecurityCritical]
        static Action waitOnBeginRequestWithFlow; 
        [SecurityCritical] 
        static ContextCallback contextOnBeginRequest;
        [SecurityCritical] 
        static AsyncCallback processRequestCompleteCallback;


        [ThreadStatic] 
        static AutoResetEvent waitObject;
 
        static Nullable iisSupportsExtendedProtection; 

        [Fx.Tag.SecurityNote(Critical = "Keeps track of impersonated user, caller must use with care")] 
        [SecurityCritical]
        HostedImpersonationContext impersonationContext;

        [Fx.Tag.SecurityNote(Critical = "Keeps track of thread static data (HttpContext, CurrentCulture, CurrentUICulture) that is used for AspNetCompatibility mode, caller must use with care")] 
        [SecurityCritical]
        HostedThreadData hostedThreadData; 
 
        [Fx.Tag.SecurityNote(Critical =
            "This field is used to manipulate request/responses using APIs protected by LinkDemand." + 
            "It is critical because we use it to determine whether we believe we're being hosted in ASP.NET or not." +
            "The field is set in the constructor of this class and we deem it safe because:" +
            "    1) all paths that lead to the .ctor are SecurityCritical and" +
            "    2) those paths have called ServiceHostingEnvironment.EnsureInitialized (which is also critical)" + 
            "So if the field is non-null, it's safe to say that we're hosted in ASP.NET, hence all the helper methods in this class that touch this field can be SecurityTreatAsSafe")]
        [SecurityCritical] 
        HttpApplication context; 

        int state; 

        [Fx.Tag.SecurityNote(Critical = "Determines whether to set the HttpContext on the outgoing thread.")]
        [SecurityCritical]
        bool flowContext; 
        bool ensureWFService;
        string configurationBasedServiceVirtualPath; 
 
        [Fx.Tag.SecurityNote(Critical = "Captures HostedImpersonationContext which must be done in the right place, and calls unsafe" +
        "ScheduleCallbackLowPriNoFlow and ScriptTimeout.  Called outside of user security context.")] 
        [SecurityCritical]
        public HostedHttpRequestAsyncResult(HttpApplication context, bool flowContext, bool ensureWFService, AsyncCallback callback, object state) :
            this(context, null, flowContext, ensureWFService, callback, state)
        { 
        }
 
        [Fx.Tag.SecurityNote(Critical = "Captures HostedImpersonationContext which must be done in the right place, and calls unsafe" + 
            "ScheduleCallbackLowPriNoFlow and ScriptTimeout.  Called outside of user security context.")]
        [SecurityCritical] 
        public HostedHttpRequestAsyncResult(HttpApplication context, string aspNetRouteServiceVirtualPath, bool flowContext, bool ensureWFService, AsyncCallback callback, object state) :
            base(callback, state)
        {
            if (context == null) 
            {
                throw FxTrace.Exception.ArgumentNull("context"); 
            } 
            this.context = context;
            this.flowContext = flowContext; 
            if (ensureWFService)
            {
                // check for CBA scenario. if true, service should be handled by WCF instead of WF,
                // set this.ensureWFservice to false 
                if (ServiceHostingEnvironment.IsConfigurationBasedService(context, out this.configurationBasedServiceVirtualPath))
                { 
                    this.ensureWFService = false; 
                }
                else 
                {
                    this.ensureWFService = true;
                }
            } 

            if (!string.IsNullOrEmpty(aspNetRouteServiceVirtualPath)) 
            { 
                // aspnet routing can hijack CBA request as we append {*pathInfo} to urlpattern and there is no real file for CBA
                // check for CBA scenario. if the request is hijacked. i.e., 
                // 1) route maps to a virtual directory:
                // aspNetRouteServiceVirtualPath <> context.Request.AppRelativeCurrentExecutionFilePath == configurationBasedServiceVirtualPath
                // if RouteExistingFiles <> true, set aspnetRouteServiceVirtualPath to null so that the request will be treated as CBA
                // if RouteExistingFiles == true, this hijack is by-design, do nothing 
                // 2) route maps to a CBA entry:
                // aspNetRouteServiceVirtualPath == context.Request.AppRelativeCurrentExecutionFilePath == configurationBasedServiceVirtualPath 
                // we will use RouteExistingFiles to decide which service should be activated. We do it in ServiceHostingEnviroment.HostingManager, 
                // as we cannot pass this info to the latter.
                if (!RouteTable.Routes.RouteExistingFiles && 
                    ServiceHostingEnvironment.IsConfigurationBasedService(context, out this.configurationBasedServiceVirtualPath))
                {
                    this.AspNetRouteServiceVirtualPath = null;
                } 
                else
                { 
                    this.AspNetRouteServiceVirtualPath = aspNetRouteServiceVirtualPath; 
                }
            } 

            // If this is a DEBUG request, complete right away and let ASP.NET handle it.
            string method = context.Request.HttpMethod ?? "";
            char firstMethodChar = method.Length == 5 ? method[0] : '\0'; 
            if ((firstMethodChar == 'd' || firstMethodChar == 'D') &&
                string.Compare(method, "DEBUG", StringComparison.OrdinalIgnoreCase) == 0) 
            { 
                if (DiagnosticUtility.ShouldTraceVerbose)
                { 
                    TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.WebHostDebugRequest, SR.TraceCodeWebHostDebugRequest, this);
                }

                this.state = State.Completed; 
                Complete(true, null);
                return; 
            } 

            this.impersonationContext = new HostedImpersonationContext(); 

            if (flowContext)
            {
                if (ServiceHostingEnvironment.AspNetCompatibilityEnabled) 
                {
                    // Capture HttpContext/culture context if necessary.  Can be used later by HostedHttpInput to re-apply 
                    // the culture during dispatch.  Also flowed here. 
                    hostedThreadData = new HostedThreadData();
                } 
            }

            // Set this up before calling IncrementRequestCount so if it fails, we don't leak a count.
            Action iotsCallback = (AspNetPartialTrustHelpers.NeedPartialTrustInvoke || flowContext) ? 
                WaitOnBeginRequestWithFlow : WaitOnBeginRequest;
 
            // Tell ASPNET to by-pass all the other events so no other http modules will 
            // be invoked, Indigo basically takes over the request completely. This should
            // only be called in non-AspNetCompatibilityEnabled mode. 
            if (!ServiceHostingEnvironment.AspNetCompatibilityEnabled && !this.ensureWFService)
            {
                context.CompleteRequest();
            } 

            // Prevent ASP.NET from generating thread aborts in relation to this request. 
            context.Server.ScriptTimeout = int.MaxValue; 

            ServiceHostingEnvironment.IncrementRequestCount(); 

            IOThreadScheduler.ScheduleCallbackLowPriNoFlow(iotsCallback, this);
        }
 
        public static WindowsIdentity AnonymousIdentity
        { 
            [Fx.Tag.SecurityNote(Critical = "Access the value of corresponding static field and prevent someone from changing its value")] 
            [SecuritySafeCritical]
            get 
            {
                if (anonymousIdentity == null)
                {
                    anonymousIdentity = WindowsIdentity.GetAnonymous(); 
                }
                return anonymousIdentity; 
            } 
        }
 
        public static Action WaitOnBeginRequest
        {
            [Fx.Tag.SecurityNote(Critical = "Access the value of corresponding static field and prevent someone from changing its value")]
            [SecuritySafeCritical] 
            get
            { 
                if (waitOnBeginRequest == null) 
                {
                    waitOnBeginRequest = new Action(OnBeginRequest); 
                }
                return waitOnBeginRequest;
            }
        } 

        public static Action WaitOnBeginRequestWithFlow 
        { 
            [Fx.Tag.SecurityNote(Critical = "Access the value of corresponding static field and prevent someone from changing its value")]
            [SecuritySafeCritical] 
            get
            {
                if (waitOnBeginRequestWithFlow == null)
                { 
                    waitOnBeginRequestWithFlow = new Action(OnBeginRequestWithFlow);
                } 
                return waitOnBeginRequestWithFlow; 
            }
        } 

        public static ContextCallback ContextOnBeginRequest
        {
            [Fx.Tag.SecurityNote(Critical = "Access the value of corresponding static field and prevent someone from changing its value")] 
            [SecuritySafeCritical]
            get 
            { 
                if (contextOnBeginRequest == null)
                { 
                    contextOnBeginRequest = new ContextCallback(OnBeginRequest);
                }
                return contextOnBeginRequest;
            } 
        }
 
        public static AsyncCallback ProcessRequestCompleteCallback 
        {
            [Fx.Tag.SecurityNote(Critical = "Access the value of corresponding static field and prevent someone from changing its value")] 
            [SecuritySafeCritical]
            get
            {
                if (processRequestCompleteCallback == null) 
                {
                    processRequestCompleteCallback = Fx.ThunkCallback(new AsyncCallback(ProcessRequestComplete)); 
                } 
                return processRequestCompleteCallback;
            } 
        }

        public bool IISSupportsExtendedProtection
        { 
            get
            { 
                if (HostedHttpRequestAsyncResult.iisSupportsExtendedProtection == null) 
                {
                    HostedHttpRequestAsyncResult.iisSupportsExtendedProtection = this.IISSupportsExtendedProtectionInternal(); 
                }
                return HostedHttpRequestAsyncResult.iisSupportsExtendedProtection.Value;
            }
        } 

        [Fx.Tag.SecurityNote(Critical = "Touches critical field context.", Safe = "Does not leak control or data, no potential for harm.")] 
        [SecuritySafeCritical] 
        [MethodImpl(MethodImplOptions.NoInlining)]
        [PermissionSetAttribute(SecurityAction.Assert, Unrestricted = true)] 
        private bool IISSupportsExtendedProtectionInternal()
        {
            DiagnosticUtility.DebugAssert(ExtendedProtectionPolicy.OSSupportsExtendedProtection, "OS must support ExtendedProtection");
 
            try
            { 
                ChannelBinding cbt = this.context.Request.HttpChannelBinding; 
                return true;
            } 
            catch (PlatformNotSupportedException)
            {
                // contract with Asp.Net is that they will always throw a PlatformNotSupportedException if IIS is not patched for CBT yet
                return false; 
            }
            catch (COMException) 
            { 
                // If IIS is patched for CBT and an error occurs when trying to retrieve the token a COMException is thrown. Even in this
                // case we know that IIS is patched for CBT. 
                return true;
            }
        }
 

        [Fx.Tag.SecurityNote(Critical = "Captures HostedImpersonationContext which must be done in the right place, and calls unsafe" + 
            "ScheduleCallbackLowPriNoFlow and ScriptTimeout.  Called outside of user security context." + 
            "Callers of this function must call ServiceHostingEnvironment.EnsureInitialized")]
        [SecurityCritical] 
        public static void ExecuteSynchronous(HttpApplication context, bool flowContext, bool ensureWFService)
        {
            ExecuteSynchronous(context, null, flowContext, ensureWFService);
        } 

        [Fx.Tag.SecurityNote(Critical = "Captures HostedImpersonationContext which must be done in the right place, and calls unsafe" + 
            "ScheduleCallbackLowPriNoFlow and ScriptTimeout.  Called outside of user security context." + 
            "Callers of this function must call ServiceHostingEnvironment.EnsureInitialized")]
        [SecurityCritical] 
        public static void ExecuteSynchronous(HttpApplication context, string routeServiceVirtualPath, bool flowContext, bool ensureWFService)
        {
            AutoResetEvent wait = HostedHttpRequestAsyncResult.waitObject;
            if (wait == null) 
            {
                wait = new AutoResetEvent(false); 
                HostedHttpRequestAsyncResult.waitObject = wait; 
            }
 
            HostedHttpRequestAsyncResult result;
            try
            {
                result = new HostedHttpRequestAsyncResult(context, routeServiceVirtualPath, flowContext, ensureWFService, ProcessRequestCompleteCallback, wait); 
                if (!result.CompletedSynchronously)
                { 
                    wait.WaitOne(); 
                }
                wait = null; 
            }
            finally
            {
                if (wait != null) 
                {
                    // Not sure of the state anymore. 
                    HostedHttpRequestAsyncResult.waitObject = null; 
                    wait.Close();
                } 
            }

            HostedHttpRequestAsyncResult.End(result);
        } 

        [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Can be called outside of a user context.")] 
        static void ProcessRequestComplete(IAsyncResult result) 
        {
            if (!result.CompletedSynchronously) 
            {
                try
                {
                    ((AutoResetEvent)result.AsyncState).Set(); 
                }
                catch (ObjectDisposedException exception) 
                { 
                    if (DiagnosticUtility.ShouldTraceWarning)
                    { 
                        DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Warning);
                    }
                }
            } 
        }
 
        [Fx.Tag.SecurityNote(Critical = "Can be called outside of user context, accesses hostedThreadData.", 
            Safe = "Uses hostedThreadData to set HttpContext.Current, cultures to the one attached to this async-result instance.")]
        [SecuritySafeCritical] 
        static void OnBeginRequestWithFlow(object state)
        {
            HostedHttpRequestAsyncResult self = (HostedHttpRequestAsyncResult)state;
 
            IDisposable hostedThreadContext = null;
            try 
            { 
                if (self.flowContext)
                { 
                    // In AspCompat case, these are the three things that need to be flowed.  See HostedHttpInput.
                    if (self.hostedThreadData != null)
                    {
                        hostedThreadContext = self.hostedThreadData.CreateContext(); 
                    }
                } 
 
                // In full-trust, this simply calls the delegate.
                AspNetPartialTrustHelpers.PartialTrustInvoke(ContextOnBeginRequest, self); 
            }
            finally
            {
                if (hostedThreadContext != null) 
                {
                    hostedThreadContext.Dispose(); 
                } 
            }
        } 

        static void OnBeginRequest(object state)
        {
            HostedHttpRequestAsyncResult self = (HostedHttpRequestAsyncResult)state; 

            Exception completionException = null; 
            try 
            {
                self.BeginRequest(); 
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e)) 
                {
                    throw; 
                } 

                completionException = e; 
            }

            if (completionException != null)
            { 
                self.CompleteOperation(completionException);
            } 
        } 

        void BeginRequest() 
        {
            try
            {
                HandleRequest(); 
            }
            catch (EndpointNotFoundException exception) 
            { 
                if (string.Compare(GetHttpMethod(), "GET", StringComparison.OrdinalIgnoreCase) == 0)
                { 
                    // Wrap the exception into HttpException.
                    throw FxTrace.Exception.AsError(new HttpException((int)HttpStatusCode.NotFound, exception.Message, exception));
                }
 
                SetStatusCode((int)HttpStatusCode.NotFound);
                CompleteOperation(null); 
            } 
            catch (ServiceActivationException exception)
            { 
                if (string.Compare(GetHttpMethod(), "GET", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    if (exception.InnerException is HttpException)
                    { 
                        throw exception.InnerException;
                    } 
                    else 
                    {
                        throw; 
                    }
                }

                SetStatusCode((int)HttpStatusCode.InternalServerError); 
                SetStatusDescription(
                    HttpChannelUtilities.StatusDescriptionStrings.HttpStatusServiceActivationException); 
                CompleteOperation(null); 
            }
            finally 
            {
                ReleaseImpersonation();
            }
        } 

        public WindowsIdentity LogonUserIdentity 
        { 
            get
            { 
                if (this.Application.User.Identity is WindowsIdentity)
                {
                    return (WindowsIdentity)this.Application.User.Identity;
                } 
                return AnonymousIdentity;
            } 
        } 

        WindowsIdentity HttpChannelListener.IHttpAuthenticationContext.LogonUserIdentity 
        {
            get
            {
                return this.LogonUserIdentity; 
            }
        } 
 
        public HostedImpersonationContext ImpersonationContext
        { 
            [Fx.Tag.SecurityNote(Critical = "Keeps track of impersonated user, caller must use with care.",
                Safe = "Safe for Get, individual members of HostedImpersonationContext are protected.")]
            [SecuritySafeCritical]
            get 
            {
                return this.impersonationContext; 
            } 
        }
 
        public HostedThreadData HostedThreadData
        {
            [Fx.Tag.SecurityNote(Critical = "Keeps track of impersonated user, caller must use with care.",
                Safe = "Safe for Get, individual members of HostedThreadData are protected.")] 
            [SecuritySafeCritical]
            get 
            { 
                return this.hostedThreadData;
            } 
        }

        public Uri OriginalRequestUri
        { 
            get;
            private set; 
 
        }
 
        public Uri RequestUri
        {
            get;
            private set; 
        }
 
        public HttpApplication Application 
        {
            [Fx.Tag.SecurityNote(Critical = "Touches critical field context.", Safe = "Does not leak control or data, no potential for harm.")] 
            [SecuritySafeCritical]
            get
            {
                return this.context; 
            }
        } 
 
        public string AspNetRouteServiceVirtualPath
        { 
            get;
            private set;
        }
 
        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.", Safe = "Does not leak control or data, no potential for harm.")]
        [SecuritySafeCritical] 
        public Stream GetInputStream() 
        {
            try 
            {
                return this.context.Request.InputStream;
            }
            catch (HttpException hostedException) 
            {
                throw FxTrace.Exception.AsError(new CommunicationException(hostedException.Message, hostedException)); 
            } 
        }
 
        public void OnReplySent()
        {
            CompleteOperation(null);
        } 

        void CompleteOperation(Exception exception) 
        { 
            if (this.state == State.Running &&
                Interlocked.CompareExchange(ref this.state, State.Completed, State.Running) == State.Running) 
            {
                Complete(false, exception);
                ServiceHostingEnvironment.DecrementRequestCount();
            } 
        }
 
        public void Abort() 
        {
            if (this.state == State.Running && 
                Interlocked.CompareExchange(ref this.state, State.Aborted, State.Running) == State.Running)
            {
                // Closes the socket connection to the client
                Application.Response.Close(); 

                Complete(false, null); 
                ServiceHostingEnvironment.DecrementRequestCount(); 
            }
        } 

        [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Can be called outside of a user context.")]
        public static void End(IAsyncResult result)
        { 
            try
            { 
                AsyncResult.End(result); 
            }
            catch (Exception exception) 
            {
                if (!Fx.IsFatal(exception))
                {
                    // Log the exception. 
                    DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error, System.ServiceModel.Diagnostics.EventLogCategory.WebHost, System.ServiceModel.Diagnostics.EventLogEventId.WebHostFailedToProcessRequest,
                      TraceUtility.CreateSourceString(result), 
                      exception == null ? string.Empty : exception.ToString()); 
                }
                throw; 
            }
        }

        X509Certificate2 HttpChannelListener.IHttpAuthenticationContext.GetClientCertificate(out bool isValidCertificate) 
        {
            HttpClientCertificate certificateInfo = this.Application.Request.ClientCertificate; 
            isValidCertificate = certificateInfo.IsValid; 
            if (certificateInfo.IsPresent)
            { 
                return new X509Certificate2(certificateInfo.Certificate);
            }
            else
            { 
                return null;
            } 
        } 

        TraceRecord HttpChannelListener.IHttpAuthenticationContext.CreateTraceRecord() 
        {
            return new System.ServiceModel.Diagnostics.HttpRequestTraceRecord(this.Application.Request);
        }
 
        void HandleRequest()
        { 
            this.OriginalRequestUri = GetUrl(); 
            string relativeVirtualPath;
            if (!string.IsNullOrEmpty(this.AspNetRouteServiceVirtualPath)) 
            {
                relativeVirtualPath = this.AspNetRouteServiceVirtualPath;
            }
            else if (!string.IsNullOrEmpty(this.configurationBasedServiceVirtualPath)) 
            {
                relativeVirtualPath = this.configurationBasedServiceVirtualPath; 
 
            }
            else 
            {
                relativeVirtualPath = GetAppRelativeCurrentExecutionFilePath();
            }
 
            if (ensureWFService)
            { 
                bool bypass = false; 
                try
                { 
                    if (!ServiceHostingEnvironment.EnsureWorkflowService(relativeVirtualPath))
                    {
                        CompleteOperation(null);
                        bypass = true; 
                        return;
                    } 
                } 
                finally
                { 
                    if (!bypass)
                    {
                        CompleteRequest();
                    } 
                }
            } 
 
            // Support for Cassini.
            if (ServiceHostingEnvironment.IsSimpleApplicationHost) 
            {
                HostedTransportConfigurationManager.EnsureInitializedForSimpleApplicationHost(this);
            }
 
            HttpHostedTransportConfiguration transportConfiguration = HostedTransportConfigurationManager.GetConfiguration(this.OriginalRequestUri.Scheme)
                as HttpHostedTransportConfiguration; 
            HostedHttpTransportManager transportManager = null; 

            // There must be a transport binding that matches the request. 
            if (transportConfiguration != null)
            {
                transportManager = transportConfiguration.GetHttpTransportManager(this.OriginalRequestUri);
            } 

            if (transportManager == null) 
            { 
                InvalidOperationException invalidOpException = new InvalidOperationException(SR.Hosting_TransportBindingNotFound(OriginalRequestUri.ToString()));
 
                ServiceActivationException activationException = new ServiceActivationException(invalidOpException.Message, invalidOpException);

                LogServiceActivationException(activationException);
 
                throw FxTrace.Exception.AsError(activationException);
            } 
 
            this.RequestUri = new Uri(transportManager.ListenUri, this.OriginalRequestUri.PathAndQuery);
            Fx.Assert( 
                object.ReferenceEquals(this.RequestUri.Scheme, Uri.UriSchemeHttp) || object.ReferenceEquals(this.RequestUri.Scheme, Uri.UriSchemeHttps),
                "Scheme must be Http or Https.");

            ServiceHostingEnvironment.EnsureServiceAvailableFast(relativeVirtualPath); 

            transportManager.HttpContextReceived(this); 
        } 

        [Fx.Tag.SecurityNote(Critical = "Calls into an unsafe UnsafeLogEvent method", 
            Safe = "Event identities cannot be spoofed as they are constants determined inside the method")]
        [SecuritySafeCritical]
        void LogServiceActivationException(ServiceActivationException activationException)
        { 
            if (TD2.ServiceExceptionIsEnabled())
            { 
                TD2.ServiceException(activationException.ToString(), typeof(ServiceActivationException).FullName); 
            }
            DiagnosticUtility.UnsafeEventLog.UnsafeLogEvent(TraceEventType.Error, System.ServiceModel.Diagnostics.EventLogCategory.WebHost, System.ServiceModel.Diagnostics.EventLogEventId.WebHostFailedToProcessRequest, true, 
                    TraceUtility.CreateSourceString(this), activationException.ToString());
        }

        [Fx.Tag.SecurityNote(Critical = "manipulates impersonation object", 
            Safe = "Releasing the SafeHandle early could only cause a future impersonation attempt to fail. We have to handle impersonation failures well already.")]
        [SecuritySafeCritical] 
        void ReleaseImpersonation() 
        {
            if (this.impersonationContext != null) 
            {
                this.impersonationContext.Release();
            }
        } 

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects, changes properties of the HTTP response.", 
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")] 
        [SecuritySafeCritical]
        internal void SetContentType(string contentType) 
        {
            this.context.Response.ContentType = contentType;
        }
 
        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects, completes the request.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")] 
        [SecuritySafeCritical] 
        internal void CompleteRequest()
        { 
            this.context.CompleteRequest();
        }

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects, changes properties of the HTTP response.", 
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
        [SecuritySafeCritical] 
        internal void SetTransferModeToStreaming() 
        {
            this.context.Response.BufferOutput = false; 
        }

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects, changes properties of the HTTP response.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")] 
        [SecuritySafeCritical]
        internal void AppendHeader(string name, string value) 
        { 
            this.context.Response.AppendHeader(name, value);
        } 

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects, changes properties of the HTTP response.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
        [SecuritySafeCritical] 
        internal void SetStatusCode(int statusCode)
        { 
            this.context.Response.TrySkipIisCustomErrors = true; 
            this.context.Response.StatusCode = statusCode;
        } 

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects, changes properties of the HTTP response.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
        [SecuritySafeCritical] 
        internal void SetStatusDescription(string statusDescription)
        { 
            this.context.Response.StatusDescription = statusDescription; 
        }
 
        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects, changes properties of the HTTP response.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
        [SecuritySafeCritical]
        internal void SetConnectionClose() 
        {
            this.context.Response.AppendHeader("Connection", "close"); 
        } 

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.", 
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
        [SecuritySafeCritical]
        internal byte[] GetPrereadBuffer(ref int contentLength)
        { 
            byte[] preReadBuffer = new byte[1];
            if (this.GetInputStream().Read(preReadBuffer, 0, 1) > 0) 
            { 
                contentLength = -1;
                return preReadBuffer; 
            }
            return null;
        }
 
        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")] 
        [SecuritySafeCritical] 
        internal Stream GetOutputStream()
        { 
            return this.context.Response.OutputStream;
        }

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.", 
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
        [SecuritySafeCritical] 
        internal string GetHttpMethod() 
        {
            return this.context.Request.HttpMethod; 
        }

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")] 
        [SecuritySafeCritical]
        internal string GetContentType() 
        { 
            const string ContentTypeHeaderName = "Content-Type";
            return this.context.Request.Headers[ContentTypeHeaderName]; 
        }

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")] 
        [SecuritySafeCritical]
        internal string GetContentTypeFast() 
        { 
            return this.context.Request.ContentType;
        } 

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
        [SecuritySafeCritical] 
        internal int GetContentLength()
        { 
            return this.context.Request.ContentLength; 
        }
 
        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
        [SecuritySafeCritical]
        internal string GetSoapAction() 
        {
            const string SoapActionHeaderName = "SOAPAction"; 
            return this.context.Request.Headers[SoapActionHeaderName]; 
        }
 
        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")]
        [SecuritySafeCritical]
        internal ChannelBinding GetChannelBinding() 
        {
            if (!this.IISSupportsExtendedProtection) 
            { 
                return null;
            } 

            return this.context.Request.HttpChannelBinding;
        }
 

        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.", 
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")] 
        [SecuritySafeCritical]
        string GetAppRelativeCurrentExecutionFilePath() 
        {
            return this.context.Request.AppRelativeCurrentExecutionFilePath;
        }
 
        [Fx.Tag.SecurityNote(Critical = "Calls getters with LinkDemands in ASP .NET objects.",
            Safe = "Does not leak control or mutable/harmful data, no potential for harm.")] 
        [SecuritySafeCritical] 
        Uri GetUrl()
        { 
            return this.context.Request.Url;
        }

        static class State 
        {
            internal const int Running = 0; 
            internal const int Completed = 1; 
            internal const int Aborted = 2;
        } 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK