MessageRpc.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.ServiceModel.Routing / System / ServiceModel / Routing / MessageRpc.cs / 1305376 / MessageRpc.cs

                            //---------------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------

namespace System.ServiceModel.Routing 
{
    using System; 
    using System.Collections.Generic; 
    using System.ComponentModel;
    using System.Globalization; 
    using System.Runtime;
    using System.ServiceModel;
    using System.ServiceModel.Activation;
    using System.ServiceModel.Channels; 
    using System.ServiceModel.Description;
    using System.ServiceModel.Security; 
    using System.Transactions; 
    using SR2 = System.ServiceModel.Routing.SR;
    using System.Security.Principal; 

    // This class wraps a Message, MessageBuffer (if requested), and the OperationContext
    // The message is not buffered if nobody calls MessageRpc.CreateBuffer.  If the message
    // is buffered, then we hang on to the buffer so it can be reused and Clone the message 
    // which became invalid when we buffered this message.
    class MessageRpc 
    { 
        const int ERROR_BAD_IMPERSONATION_LEVEL = 1346;
 
        Message originalMessage;
        Message clonedMessage;
        MessageBuffer messageBuffer;
        string uniqueID; 
        Transaction transaction;
        ReceiveContext receiveContext; 
        IList operations; 
        WindowsIdentity windowsIdentity;
 
        public MessageRpc(Message message, OperationContext operationContext, bool impersonationRequired)
        {
            Fx.Assert(message != null, "message cannot be null");
            Fx.Assert(operationContext != null, "operationContext cannot be null"); 

            this.originalMessage = message; 
            this.OperationContext = operationContext; 

            //passing in true causes this to return null if the thread is not impersonating. 
            this.windowsIdentity = WindowsIdentity.GetCurrent(true);
            if (impersonationRequired && !AspNetEnvironment.Current.AspNetCompatibilityEnabled)
            {
                if (this.windowsIdentity == null || this.windowsIdentity.ImpersonationLevel != TokenImpersonationLevel.Impersonation) 
                {
                    //Temporarily revert impersonation to process token to throw an exception 
                    IDisposable autoRevert = null; 
                    try
                    { 
                        try { }
                        finally
                        {
                            autoRevert = WindowsIdentity.Impersonate(IntPtr.Zero); 
                        }
 
                        Win32Exception errorDetail = new Win32Exception(ERROR_BAD_IMPERSONATION_LEVEL); 
                        throw FxTrace.Exception.AsError(new SecurityNegotiationException(errorDetail.Message));
                    } 
                    finally
                    {
                        if (autoRevert != null)
                        { 
                            autoRevert.Dispose();
                        } 
                    } 
                }
            } 

            ReceiveContext.TryGet(message, out this.receiveContext);

            this.transaction = Transaction.Current; 
            if (this.transaction == null)
            { 
                this.transaction = TransactionMessageProperty.TryGetTransaction(message); 
            }
        } 

        internal bool Impersonating
        {
            get { return this.windowsIdentity != null; } 
        }
 
        public OperationContext OperationContext 
        {
            get; 
            private set;
        }

        public string UniqueID 
        {
            get 
            { 
                if (this.uniqueID == null)
                { 
                    if (this.Message.Version != MessageVersion.None &&
                        this.Message.Headers.MessageId != null)
                    {
                        this.uniqueID = this.originalMessage.Headers.MessageId.ToString(); 
                    }
                    else 
                    { 
                        this.uniqueID = this.GetHashCode().ToString(CultureInfo.InvariantCulture);
                    } 
                }
                return this.uniqueID;
            }
        } 

        public Message Message 
        { 
            get
            { 
                // If we've created a MessageBuffer then the originalMessage has already been consumed
                if (this.messageBuffer != null)
                {
                    Fx.Assert(this.clonedMessage != null, "Need to set clonedMessage if we buffered the message"); 
                    return this.clonedMessage;
                } 
                else 
                {
                    // Haven't buffered, can use the original. 
                    return this.originalMessage;
                }
            }
        } 

        public ReceiveContext ReceiveContext 
        { 
            get { return this.receiveContext; }
        } 

        public IList Operations
        {
            get { return this.operations; } 
        }
 
        public Transaction Transaction 
        {
            get { return this.transaction; } 
        }

        public MessageBuffer CreateBuffer()
        { 
            if (this.messageBuffer == null)
            { 
                this.messageBuffer = this.originalMessage.CreateBufferedCopy(int.MaxValue); 
                this.clonedMessage = this.messageBuffer.CreateMessage();
            } 
            return this.messageBuffer;
        }

        public IDisposable PrepareCall() 
        {
            return new CallState(this); 
        } 

        public void RouteToSingleEndpoint(RoutingConfiguration routingConfig) 
        {
            IEnumerable result;
            if (routingConfig.RouteOnHeadersOnly)
            { 
                if (TD.RoutingServiceFilterTableMatchStartIsEnabled()) { TD.RoutingServiceFilterTableMatchStart(); }
                routingConfig.InternalFilterTable.GetMatchingValue(this.Message, out result); 
                if (TD.RoutingServiceFilterTableMatchStopIsEnabled()) { TD.RoutingServiceFilterTableMatchStop(); } 
            }
            else 
            {
                MessageBuffer buffer = this.CreateBuffer();

                if (TD.RoutingServiceFilterTableMatchStartIsEnabled()) { TD.RoutingServiceFilterTableMatchStart(); } 
                routingConfig.InternalFilterTable.GetMatchingValue(buffer, out result);
                if (TD.RoutingServiceFilterTableMatchStopIsEnabled()) { TD.RoutingServiceFilterTableMatchStop(); } 
            } 

            if (result == null) 
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR2.NoFilterMatched));
            }
 
            if (TD.RoutingServiceMessageRoutedToEndpointsIsEnabled())
            { 
                TD.RoutingServiceMessageRoutedToEndpoints(this.UniqueID, "1"); 
            }
 
            this.operations = new List(1);
            this.operations.Add(new SendOperation(result, typeof(TContract), this.OperationContext));
        }
 
        public void RouteToEndpoints(RoutingConfiguration routingConfig)
        { 
            List> endpointLists = new List>(); 
            if (routingConfig.RouteOnHeadersOnly)
            { 
                if (TD.RoutingServiceFilterTableMatchStartIsEnabled()) { TD.RoutingServiceFilterTableMatchStart(); }
                routingConfig.InternalFilterTable.GetMatchingValues(this.Message, endpointLists);
                if (TD.RoutingServiceFilterTableMatchStopIsEnabled()) { TD.RoutingServiceFilterTableMatchStop(); }
            } 
            else
            { 
                MessageBuffer messageBuffer = this.CreateBuffer(); 

                if (TD.RoutingServiceFilterTableMatchStartIsEnabled()) { TD.RoutingServiceFilterTableMatchStart(); } 
                routingConfig.InternalFilterTable.GetMatchingValues(messageBuffer, endpointLists);
                if (TD.RoutingServiceFilterTableMatchStopIsEnabled()) { TD.RoutingServiceFilterTableMatchStop(); }
            }
 
            if (TD.RoutingServiceMessageRoutedToEndpointsIsEnabled())
            { 
                TD.RoutingServiceMessageRoutedToEndpoints(this.UniqueID, endpointLists.Count.ToString(TD.Culture)); 
            }
            if (endpointLists.Count == 0) 
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR2.NoFilterMatched));
            }
            this.operations = new List(endpointLists.Count); 
            foreach (IEnumerable endpointList in endpointLists)
            { 
                this.operations.Add(new SendOperation(endpointList, typeof(TContract), this.OperationContext)); 
            }
        } 

        class CallState : IDisposable
        {
            OperationContextScope nullContextScope; 
            WindowsImpersonationContext impersonation;
 
            public CallState (MessageRpc messageRpc) 
 	        {
                this.nullContextScope = new OperationContextScope((OperationContext)null); 

                if (messageRpc.windowsIdentity != null)
                {
                    this.impersonation = messageRpc.windowsIdentity.Impersonate(); 
                }
            } 
 
            void IDisposable.Dispose()
            { 
                if (this.impersonation != null)
                {
                    this.impersonation.Dispose();
                } 
                this.nullContextScope.Dispose();
            } 
        } 
    }
} 

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