HostedHttpTransportManager.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Activation / HostedHttpTransportManager.cs / 1 / HostedHttpTransportManager.cs

                            //---------------------------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------------------
namespace System.ServiceModel.Activation
{ 
    using System.Collections.Generic;
    using System.ServiceModel; 
    using System.ServiceModel.Channels; 
    using System.Diagnostics;
    using System.Globalization; 
    using System.Net;
    using System.ServiceModel.Diagnostics;
    using System.Web;
    using System.Web.Hosting; 
    using System.Security.Principal;
    using System.Threading; 
    using System.Security; 
    using System.Security.Permissions;
 

    class HostedHttpTransportManager : HttpTransportManager
    {
        internal HostedHttpTransportManager(BaseUriWithWildcard baseAddress) 
        {
            this.ListenUri = baseAddress.BaseAddress; 
            this.HostNameComparisonMode = baseAddress.HostNameComparisonMode; 
        }
 
        internal override bool IsCompatible(HttpChannelListener factory)
        {
            return true;
        } 

        internal override void OnClose() 
        { 
            // empty
        } 

        internal override void OnOpen()
        {
            // empty 
        }
 
        internal override string Scheme 
        {
            get 
            {
                return this.ListenUri.Scheme;
            }
        } 

        static bool canTraceConnectionInformation = true; 
        public void TraceConnectionInformation(HostedHttpRequestAsyncResult result) 
        {
            if (result != null && DiagnosticUtility.ShouldTraceInformation && canTraceConnectionInformation) 
            {
                try
                {
                    IServiceProvider provider = (IServiceProvider)result.Application.Context; 
                    HttpWorkerRequest workerRequest = (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));
                    string localAddress = string.Format(CultureInfo.InvariantCulture, 
                        "{0}:{1}", workerRequest.GetLocalAddress(), workerRequest.GetLocalPort()); 
                    string remoteAddress = string.Format(CultureInfo.InvariantCulture,
                        "{0}:{1}", workerRequest.GetRemoteAddress(), workerRequest.GetRemotePort()); 
                    TraceUtility.TraceHttpConnectionInformation(localAddress, remoteAddress, this);
                }
                catch (SecurityException e)
                { 
                    canTraceConnectionInformation = false;
 
                    // not re-throwing on purpose 
                    if (DiagnosticUtility.ShouldTraceWarning)
                    { 
                        DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Warning);
                    }
                }
            } 
        }
 
        ///  
        /// Critical - calls getters with LinkDemands in ASP .NET objects
        ///  Safe     - only returns the activity, doesn't leak the ASP .NET objects 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        public ServiceModelActivity CreateReceiveBytesActivity(HostedHttpRequestAsyncResult result)
        { 
            ServiceModelActivity retval = null;
            if (result != null && DiagnosticUtility.ShouldUseActivity) 
            { 
                IServiceProvider provider = (IServiceProvider)result.Application.Context;
                retval = ServiceModelActivity.CreateBoundedActivity(GetRequestTraceIdentifier(provider)); 
                ServiceModelActivity.Start(retval, SR.GetString(SR.ActivityReceiveBytes, result.RequestUri.ToString()), ActivityType.ReceiveBytes);
            }
            return retval;
        } 

        ///  
        ///  Critical - uses the HttpWorkerRequest to get the trace identifier, which Demands UnamangedCode 
        ///  Safe     - only returns the trace id, doesn't leak the HttpWorkerRequest
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        [SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)]
        static Guid GetRequestTraceIdentifier(IServiceProvider provider)
        { 
            return ((HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest))).RequestTraceIdentifier;
        } 
 
        internal void HttpContextReceived(HostedHttpRequestAsyncResult result)
        { 
            using (DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.BoundOperation(this.Activity) : null)
            {
                using (this.CreateReceiveBytesActivity(result))
                { 
                    this.TraceConnectionInformation(result);
                    HttpChannelListener listener; 
                    if (base.TryLookupUri(result.RequestUri, result.GetHttpMethod(), 
                        this.HostNameComparisonMode, out listener))
                    { 
                        HostedHttpContext hostedContext =
                            (HostedHttpContext)HttpRequestContext.CreateContext(listener, result);
                        listener.HttpContextReceived(hostedContext, null);
                        return; 
                    }
 
                    if (DiagnosticUtility.ShouldTraceError) 
                    {
                        TraceUtility.TraceEvent(TraceEventType.Error, TraceCode.HttpChannelMessageReceiveFailed, 
                            new StringTraceRecord("IsRecycling", ServiceHostingEnvironment.IsRecycling.ToString(CultureInfo.CurrentCulture)),
                            this, null);
                    }
 
                    if (ServiceHostingEnvironment.IsRecycling)
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                            new EndpointNotFoundException(SR.GetString(SR.Hosting_ListenerNotFoundForActivationInRecycling, result.RequestUri.ToString())));
                    } 
                    else
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                            new EndpointNotFoundException(SR.GetString(SR.Hosting_ListenerNotFoundForActivation, result.RequestUri.ToString()))); 
                    }
                } 
            } 
        }
    } 

    sealed class HostingMessageProperty
    {
        const string name = "webhost"; 

        ///  
        /// Critical - keeps track of impersonated user, caller must use with care and call Dispose at the appropriate time 
        /// 
        [SecurityCritical] 
        HostedImpersonationContext impersonationContext;

        /// 
        /// Critical - stores a SecurityCritical helper class that controls HttpContext.Current with an elevation 
        ///            need to ensure that HostedThreadData is constructed and used properly
        ///  
        [SecurityCritical] 
        HostedThreadData currentThreadData;
 
        /// 
        /// Critical - sets impersonation context from an arbitrary source, caller must guard
        /// 
        [SecurityCritical] 
        internal HostingMessageProperty(HostedHttpRequestAsyncResult result)
        { 
            if (!ServiceHostingEnvironment.IsHosted) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.Hosting_ProcessNotExecutingUnderHostedContext, "HostingMessageProperty")));
 
            if (ServiceHostingEnvironment.AspNetCompatibilityEnabled)
            {
                if (result.ImpersonationContext != null && result.ImpersonationContext.IsImpersonated)
                { 
                    this.impersonationContext = result.ImpersonationContext;
                    this.impersonationContext.AddRef(); 
                } 

                currentThreadData = result.HostedThreadData; 
            }
        }

        static internal string Name 
        {
            get 
            { 
                return name;
            } 
        }

        internal HostedImpersonationContext ImpersonationContext
        { 
            /// 
            /// Critical - keeps track of impersonated user, caller must use with care 
            /// Safe - safe for Get, individual members of HostedImpersonationContext are protected 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get
            {
                return impersonationContext;
            } 
        }
 
        ///  
        /// Critical - delegates to a SecurityCritical method in HostedThreadData. caller must ensure that function is called appropriately
        ///            and result is guarded and Dispose()'d correctly. 
        /// 
        [SecurityCritical]
        internal IDisposable ApplyIntegrationContext()
        { 
            if (ServiceHostingEnvironment.AspNetCompatibilityEnabled)
            { 
                return currentThreadData.CreateContext(); 
            }
 
            return null;
        }

        ///  
        /// Critical - clean up impersonationContext, which is critical
        /// Safe - doesn't leak anything 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        public void Close() 
        {
            if (impersonationContext != null)
            {
                impersonationContext.Release(); 
                impersonationContext = null;
            } 
        } 
    }
 
        /// 
        /// Critical - captures HttpContext.Current on construction, then can apply that state at a later time and reset on Dispose
        ///            whole thing is critical because where it was initially constructed can be used to control HttpContext.set_Current later
        ///            and HttpContext.set_Current requires an elevation 
        /// 
    [SecurityCritical(SecurityCriticalScope.Everything)] 
    class HostedThreadData 
    {
        CultureInfo cultureInfo; 
        CultureInfo uiCultureInfo;
        HttpContext httpContext;

        public HostedThreadData() 
        {
            this.cultureInfo = CultureInfo.CurrentCulture; 
            this.uiCultureInfo = CultureInfo.CurrentUICulture; 
            this.httpContext = HttpContext.Current;
        } 

        public IDisposable CreateContext()
        {
            return new HostedAspNetContext(this); 
        }
 
        [SecurityPermission(SecurityAction.Assert, Unrestricted = true)] 
        static void UnsafeApplyData(HostedThreadData data)
        { 
            // We set the CallContext.HostContext directly instead of setting HttpContext.Current because
            // the latter uses a demand instead of a link demand, which is very expensive in partial trust.
            System.Runtime.Remoting.Messaging.CallContext.HostContext = data.httpContext;
 
            Thread currentThread = Thread.CurrentThread;
            if (currentThread.CurrentCulture != data.cultureInfo) 
            { 
                currentThread.CurrentCulture = data.cultureInfo;
            } 

            if (currentThread.CurrentUICulture != data.uiCultureInfo)
            {
                currentThread.CurrentUICulture = data.uiCultureInfo; 
            }
        } 
 
        class HostedAspNetContext : IDisposable
        { 
            HostedThreadData oldData;

            public HostedAspNetContext(HostedThreadData newData)
            { 
                oldData = new HostedThreadData();
                HostedThreadData.UnsafeApplyData(newData); 
            } 

            public void Dispose() 
            {
                HostedThreadData.UnsafeApplyData(oldData);
            }
        } 

    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

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