HostedHttpContext.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 / HostedHttpContext.cs / 4 / HostedHttpContext.cs

                            //---------------------------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------------------
namespace System.ServiceModel.Activation
{ 
    using System.Net;
    using System.ServiceModel; 
    using System.Web; 
    using System.ServiceModel.Security;
    using System.IO; 
    using System.Threading;
    using System.ServiceModel.Channels;
    using System.Collections.Specialized;
    using System.Security; 

    class HostedHttpContext : HttpRequestContext 
    { 
        internal const string OriginalHttpRequestUriPropertyName = "OriginalHttpRequestUri";
 
        HostedHttpRequestAsyncResult result;

        public HostedHttpContext(HttpChannelListener listener, HostedHttpRequestAsyncResult result)
            : base(listener, null) 
        {
            this.result = result; 
        } 

        public override string HttpMethod 
        {
            get
            {
                return result.GetHttpMethod(); 
            }
        } 
 
        protected override SecurityMessageProperty OnProcessAuthentication()
        { 
            return Listener.ProcessAuthentication(this.result);
        }

        protected override HttpStatusCode ValidateAuthentication() 
        {
            return Listener.ValidateAuthentication(this.result); 
        } 

        // Accessing the headers of an already replied HttpRequest instance causes an Access Violation in hosted mode. 
        // In one-way scenarios, reply happens before the user gets the message. That's why we are removing all the
        // references to HttpRequest in RequestMessage.
        void RemoveHostedRequestContainer()
        { 
            Message requestMessage = this.InternalRequestMessage;
            if (requestMessage != null && requestMessage.State != MessageState.Closed) 
            { 
                object value;
                if (requestMessage.Properties.TryGetValue(HttpRequestMessageProperty.Name, out value)) 
                {
                    HttpRequestMessageProperty property = (HttpRequestMessageProperty)value;
                    property.MakeRequestContainerNull();
                } 
                requestMessage.Properties.Remove(RemoteEndpointMessageProperty.Name);
            } 
        } 

        protected override void OnReply(Message message, TimeSpan timeout) 
        {
            this.RemoveHostedRequestContainer();
            base.OnReply(message, timeout);
        } 

        protected override IAsyncResult OnBeginReply( 
            Message message, TimeSpan timeout, AsyncCallback callback, object state) 
        {
            this.RemoveHostedRequestContainer(); 
            return base.OnBeginReply(message, timeout, callback, state);
        }

        protected override void OnAbort() 
        {
            base.OnAbort(); 
            result.Abort(); 
        }
 
        protected override HttpInput GetHttpInput()
        {
            return new HostedHttpInput(this);
        } 

        protected override HttpOutput GetHttpOutput(Message message) 
        { 
            // work around http.sys keep alive bug with chunked requests, see MB 49676, this is fixed in Vista
            if ((this.HttpInput.ContentLength == -1 && !OSEnvironmentHelper.IsVistaOrGreater) || !this.KeepAliveEnabled) 
            {
                result.SetConnectionClose();
            }
            return HttpOutput.CreateHttpOutput(result, Listener, message, this); 
        }
 
        protected override void OnClose(TimeSpan timeout) 
        {
            base.OnClose(timeout); 
            result.OnReplySent();
        }

        class HostedHttpInput : HttpInput 
        {
            int contentLength; 
            string contentType; 
            HostedHttpContext hostedHttpContext;
            byte[] preReadBuffer; 

            public HostedHttpInput(HostedHttpContext hostedHttpContext)
                : base(hostedHttpContext.Listener, true)
            { 
                this.hostedHttpContext = hostedHttpContext;
 
                EnvelopeVersion envelopeVersion = hostedHttpContext.Listener.MessageEncoderFactory.Encoder.MessageVersion.Envelope; 

                // MB#29602, perf optimization 
                if (envelopeVersion == EnvelopeVersion.Soap11)
                {
                    // For soap 1.1, use headers collection to get content-type since we need to pull in the headers
                    // collection for SOAP-Action anyways 
                    this.contentType = hostedHttpContext.result.GetContentType();
                } 
                else 
                {
                    // For soap 1.2, the we pull the action header from the content-type, so don't access the headers 
                    // and just use the typed property. For other versions, we shouldn't need the headers up front.
                    this.contentType = hostedHttpContext.result.GetContentTypeFast();
                }
 
                this.contentLength = hostedHttpContext.result.GetContentLength();
 
                // MB#34947: System.Web signals chunked as 0 as well so the only way we can 
                // differentiate is by reading ahead
                if (this.contentLength == 0) 
                {
                    preReadBuffer = hostedHttpContext.result.GetPrereadBuffer(ref this.contentLength);
                }
            } 

            public override long ContentLength 
            { 
                get
                { 
                    return this.contentLength;
                }
            }
 
            protected override string ContentType
            { 
                get 
                {
                    return this.contentType; 
                }
            }

            protected override bool HasContent 
            {
                get { return (this.preReadBuffer != null || this.ContentLength > 0); } 
            } 

            protected override string SoapActionHeader 
            {
                get
                {
                    return hostedHttpContext.result.GetSoapAction(); 
                }
            } 
 
            protected override void AddProperties(Message message)
            { 
                HostedRequestContainer requestContainer = new HostedRequestContainer(this.hostedHttpContext.result);

                HttpRequestMessageProperty requestProperty =
                    new HttpRequestMessageProperty(requestContainer); 

                requestProperty.Method = this.hostedHttpContext.HttpMethod; 
 
                // Uri.Query always includes the '?'
                if (this.hostedHttpContext.result.RequestUri.Query.Length > 1) 
                {
                    requestProperty.QueryString = this.hostedHttpContext.result.RequestUri.Query.Substring(1);
                }
 
                message.Properties.Add(HttpRequestMessageProperty.Name, requestProperty);
 
                message.Properties.Add(HostingMessageProperty.Name, CreateMessagePropertyFromHostedResult(this.hostedHttpContext.result)); 
                message.Properties.Via = this.hostedHttpContext.result.RequestUri;
 
                RemoteEndpointMessageProperty remoteEndpointProperty =
                    new RemoteEndpointMessageProperty(requestContainer);

                message.Properties.Add(RemoteEndpointMessageProperty.Name, remoteEndpointProperty); 

                message.Properties.Add(OriginalHttpRequestUriPropertyName, this.hostedHttpContext.result.OriginalRequestUri); 
            } 

            ///  
            /// Critical - calls critical .ctor(HostedImpersonationContext)
            /// Safe - only accepts the incoming context from HostedHttpRequestAsyncResult which stores the context in a critical field
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            static HostingMessageProperty CreateMessagePropertyFromHostedResult(HostedHttpRequestAsyncResult result)
            { 
                return new HostingMessageProperty(result); 
            }
 
            protected override Stream GetInputStream()
            {
                if (this.preReadBuffer != null)
                { 
                    return new HostedInputStream(this.hostedHttpContext, this.preReadBuffer);;
                } 
                else 
                {
                    return new HostedInputStream(this.hostedHttpContext); 
                }
            }

            class HostedInputStream : HttpDelayedAcceptStream 
            {
                public HostedInputStream(HostedHttpContext hostedContext) 
                    : base(hostedContext.result.GetInputStream()) 
                {
                } 

                public HostedInputStream(HostedHttpContext hostedContext, byte[] preReadBuffer)
                    : base(new PreReadStream(hostedContext.result.GetInputStream(), preReadBuffer))
                { 
                }
 
                public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) 
                {
                    return base.BeginRead(buffer, offset, count, callback, state); 
                }

                public override int EndRead(IAsyncResult result)
                { 
                    return base.EndRead(result);
                } 
 
                public override int Read(byte[] buffer, int offset, int count)
                { 
                    return base.Read(buffer, offset, count);
                }
            }
        } 
    }
 
    class HostedRequestContainer 
    {
        HostedHttpRequestAsyncResult result; 

        public HostedRequestContainer(HostedHttpRequestAsyncResult result)
        {
            this.result = result; 
        }
 
        ///  
        /// Critical - calls getters with LinkDemands in ASP .NET objects
        /// Safe - does not leak control or mutable/harmful data, no potential for harm 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        public void CopyHeaders(WebHeaderCollection headers)
        { 
            headers.Add(this.result.Application.Request.Headers);
        } 
 
        /// 
        /// Critical - calls getters with LinkDemands in ASP .NET objects 
        /// Safe - does not leak control or mutable/harmful data, no potential for harm
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        public string GetRemoteAddress() 
        {
            return this.result.Application.Request.UserHostAddress; 
        } 

        ///  
        /// Critical - calls getters with LinkDemands in ASP .NET objects
        /// Safe - does not leak control or mutable/harmful data, no potential for harm
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        public int GetRemotePort()
        { 
            int port; 

            string remotePort = this.result.Application.Request.ServerVariables["REMOTE_PORT"]; 
            if (string.IsNullOrEmpty(remotePort) || !int.TryParse(remotePort, out port))
            {
                port = 0;
            } 

            return port; 
        } 
    }
} 

// 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