Пример #1
0
 internal void Add(string action, DispatchOperationRuntime operation)
 {
     if (map.Contains(action))
     {
         DispatchOperationRuntime existingOperation = (DispatchOperationRuntime)map[action];
         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.SFxActionDemuxerDuplicate, existingOperation.Name, operation.Name, action)));
     }
     map.Add(action, operation);
 }
        internal ImmutableDispatchRuntime(DispatchRuntime dispatch)
        {
            _authenticationBehavior = AuthenticationBehavior.TryCreate(dispatch);
            _authorizationBehavior  = AuthorizationBehavior.TryCreate(dispatch);
            _concurrency            = new ConcurrencyBehavior(dispatch);
            _error        = new ErrorBehavior(dispatch.ChannelDispatcher);
            _enableFaults = dispatch.EnableFaults;
            _inputSessionShutdownHandlers = EmptyArray <IInputSessionShutdown> .ToArray(dispatch.InputSessionShutdownHandlers);

            InstanceBehavior   = new InstanceBehavior(dispatch, this);
            _isOnServer        = dispatch.IsOnServer;
            _manualAddressing  = dispatch.ManualAddressing;
            _messageInspectors = EmptyArray <IDispatchMessageInspector> .ToArray(dispatch.MessageInspectors);

            _securityImpersonation = SecurityImpersonationBehavior.CreateIfNecessary(dispatch);
            RequireClaimsPrincipalOnOperationContext = dispatch.RequireClaimsPrincipalOnOperationContext;
            _impersonateOnSerializingReply           = dispatch.ImpersonateOnSerializingReply;
            _terminate             = TerminatingOperationBehavior.CreateIfNecessary(dispatch);
            _thread                = new ThreadBehavior(dispatch);
            ValidateMustUnderstand = dispatch.ValidateMustUnderstand;
            ParameterInspectorCorrelationOffset = (dispatch.MessageInspectors.Count +
                                                   dispatch.MaxCallContextInitializers);
            _correlationCount = ParameterInspectorCorrelationOffset + dispatch.MaxParameterInspectors;

            DispatchOperationRuntime unhandled = new DispatchOperationRuntime(dispatch.UnhandledDispatchOperation, this);

            if (dispatch.OperationSelector == null)
            {
                ActionDemuxer demuxer = new ActionDemuxer();
                for (int i = 0; i < dispatch.Operations.Count; i++)
                {
                    DispatchOperation        operation        = dispatch.Operations[i];
                    DispatchOperationRuntime operationRuntime = new DispatchOperationRuntime(operation, this);
                    demuxer.Add(operation.Action, operationRuntime);
                }

                demuxer.SetUnhandled(unhandled);
                _demuxer = demuxer;
            }
            else
            {
                CustomDemuxer demuxer = new CustomDemuxer(dispatch.OperationSelector);
                for (int i = 0; i < dispatch.Operations.Count; i++)
                {
                    DispatchOperation        operation        = dispatch.Operations[i];
                    DispatchOperationRuntime operationRuntime = new DispatchOperationRuntime(operation, this);
                    demuxer.Add(operation.Name, operationRuntime);
                }

                demuxer.SetUnhandled(unhandled);
                _demuxer = demuxer;
            }

            _processMessageNonCleanupError = new MessageRpcErrorHandler(ProcessMessageNonCleanupError);
            _processMessageCleanupError    = new MessageRpcErrorHandler(ProcessMessageCleanupError);
        }
            public DispatchOperationRuntime GetOperation(ref Message request)
            {
                string operationName = _selector.SelectOperation(ref request);
                DispatchOperationRuntime operation = null;

                if (_map.TryGetValue(operationName, out operation))
                {
                    return(operation);
                }
                else
                {
                    return(_unhandled);
                }
            }
Пример #4
0
            public DispatchOperationRuntime GetOperation(ref Message request)
            {
                string action = request.Headers.Action;

                if (action == null)
                {
                    action = MessageHeaders.WildcardAction;
                }
                DispatchOperationRuntime operation = (DispatchOperationRuntime)map[action];

                if (operation != null)
                {
                    return(operation);
                }

                return(unhandled);
            }
Пример #5
0
        private async Task DispatchAndReleasePumpAsync(RequestContext request, bool cleanThread, RequestInfo requestInfo)
        {
            OperationContext   currentOperationContext = null;
            ServiceChannel     channel  = requestInfo.Channel;
            EndpointDispatcher endpoint = requestInfo.Endpoint;
            bool releasedPump           = false;

            try
            {
                DispatchRuntime dispatchBehavior = requestInfo.DispatchRuntime;

                if (channel == null || dispatchBehavior == null)
                {
                    Fx.Assert("System.ServiceModel.Dispatcher.ChannelHandler.Dispatch(): (channel == null || dispatchBehavior == null)");
                    return;
                }

                Message message;

                //EventTraceActivity eventTraceActivity = TraceDispatchMessageStart(request.RequestMessage);
                message = request.RequestMessage;

                DispatchOperationRuntime operation = dispatchBehavior.GetOperation(ref message);
                if (operation == null)
                {
                    Fx.Assert("ChannelHandler.Dispatch (operation == null)");
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "No DispatchOperationRuntime found to process message.")));
                }

                if (_shouldRejectMessageWithOnOpenActionHeader && message.Headers.Action == OperationDescription.SessionOpenedAction)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.SFxNoEndpointMatchingAddressForConnectionOpeningMessage, message.Headers.Action, "Open")));
                }

                //if (MessageLogger.LoggingEnabled)
                //{
                //    MessageLogger.LogMessage(ref message, (operation.IsOneWay ? MessageLoggingSource.ServiceLevelReceiveDatagram : MessageLoggingSource.ServiceLevelReceiveRequest) | MessageLoggingSource.LastChance);
                //}

                if (operation.IsTerminating && _hasSession)
                {
                    _isChannelTerminated = true;
                }

                bool hasOperationContextBeenSet;
                if (currentOperationContext != null)
                {
                    hasOperationContextBeenSet = true;
                    currentOperationContext.ReInit(request, message, channel);
                }
                else
                {
                    hasOperationContextBeenSet = false;
                    currentOperationContext    = new OperationContext(request, message, channel, _host);
                }

                if (currentOperationContext.EndpointDispatcher == null && _serviceDispatcher != null)
                {
                    currentOperationContext.EndpointDispatcher = endpoint;
                }

                var rpc = new MessageRpc(request, message, operation, channel, _host,
                                         this, cleanThread, currentOperationContext, requestInfo.ExistingInstanceContext);

                //TraceUtility.MessageFlowAtMessageReceived(message, currentOperationContext, eventTraceActivity, true);

                // passing responsibility for call throttle to MessageRpc
                // (MessageRpc implicitly owns this throttle once it's created)
                requestInfo.ChannelHandlerOwnsCallThrottle = false;
                // explicitly passing responsibility for instance throttle to MessageRpc
                rpc.MessageRpcOwnsInstanceContextThrottle             = requestInfo.ChannelHandlerOwnsInstanceContextThrottle;
                requestInfo.ChannelHandlerOwnsInstanceContextThrottle = false;

                // These need to happen before Dispatch but after accessing any ChannelHandler
                // state, because we go multi-threaded after this
                ReleasePump();
                releasedPump = true;

                await operation.Parent.DispatchAsync(rpc, hasOperationContextBeenSet);
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }

                await HandleErrorAsync(e, request, requestInfo, channel);
            }
            finally
            {
                if (!releasedPump)
                {
                    ReleasePump();
                }
            }
        }
Пример #6
0
        //bool didTraceProcessMessage1 = false;
        //bool didTraceProcessMessage2 = false;
        //bool didTraceProcessMessage3 = false;
        //bool didTraceProcessMessage31 = false;
        //bool didTraceProcessMessage4 = false;
        //bool didTraceProcessMessage41 = false;

        internal ImmutableDispatchRuntime(DispatchRuntime dispatch)
        {
            //this.authenticationBehavior = AuthenticationBehavior.TryCreate(dispatch);
            //this.authorizationBehavior = AuthorizationBehavior.TryCreate(dispatch);
            concurrency  = new ConcurrencyBehavior(dispatch);
            error        = new ErrorBehavior(dispatch.ChannelDispatcher);
            enableFaults = dispatch.EnableFaults;
            inputSessionShutdownHandlers = EmptyArray <IInputSessionShutdown> .ToArray(dispatch.InputSessionShutdownHandlers);

            instance          = new InstanceBehavior(dispatch, this);
            isOnServer        = dispatch.IsOnServer;
            manualAddressing  = dispatch.ManualAddressing;
            messageInspectors = EmptyArray <IDispatchMessageInspector> .ToArray(dispatch.MessageInspectors);

            //this.requestReplyCorrelator = new RequestReplyCorrelator();
            //this.securityImpersonation = SecurityImpersonationBehavior.CreateIfNecessary(dispatch);
            //this.RequireClaimsPrincipalOnOperationContext = dispatch.RequireClaimsPrincipalOnOperationContext;
            //this.impersonateOnSerializingReply = dispatch.ImpersonateOnSerializingReply;
            terminate = TerminatingOperationBehavior.CreateIfNecessary(dispatch);
            thread    = new ThreadBehavior(dispatch);
            ValidateMustUnderstand = dispatch.ValidateMustUnderstand;
            //this.ignoreTransactionFlow = dispatch.IgnoreTransactionMessageProperty;
            //this.transaction = TransactionBehavior.CreateIfNeeded(dispatch);
            //sendAsynchronously = dispatch.ChannelDispatcher.SendAsynchronously;
            ParameterInspectorCorrelationOffset = (dispatch.MessageInspectors.Count +
                                                   dispatch.MaxCallContextInitializers);
            correlationCount = ParameterInspectorCorrelationOffset + dispatch.MaxParameterInspectors;

            DispatchOperationRuntime unhandled = new DispatchOperationRuntime(dispatch.UnhandledDispatchOperation, this);

            if (dispatch.OperationSelector == null)
            {
                ActionDemuxer demuxer = new ActionDemuxer();
                for (int i = 0; i < dispatch.Operations.Count; i++)
                {
                    DispatchOperation        operation        = dispatch.Operations[i];
                    DispatchOperationRuntime operationRuntime = new DispatchOperationRuntime(operation, this);
                    demuxer.Add(operation.Action, operationRuntime);
                }

                demuxer.SetUnhandled(unhandled);
                this.demuxer = demuxer;
            }
            else
            {
                throw new PlatformNotSupportedException();
                //    CustomDemuxer demuxer = new CustomDemuxer(dispatch.OperationSelector);
                //    for (int i = 0; i < dispatch.Operations.Count; i++)
                //    {
                //        DispatchOperation operation = dispatch.Operations[i];
                //        DispatchOperationRuntime operationRuntime = new DispatchOperationRuntime(operation, this);
                //        demuxer.Add(operation.Name, operationRuntime);
                //    }

                //    demuxer.SetUnhandled(unhandled);
                //    this.demuxer = demuxer;
            }

            //processMessage1 = new MessageRpcProcessor(ProcessMessage1);
            //processMessage11 = new MessageRpcProcessor(ProcessMessage11);
            //processMessage2 = new MessageRpcProcessor(ProcessMessage2);
            //processMessage3 = new MessageRpcProcessor(ProcessMessage3);
            //processMessage31 = new MessageRpcProcessor(ProcessMessage31);
            //processMessage4 = new MessageRpcProcessor(ProcessMessage4);
            //processMessage41 = new MessageRpcProcessor(ProcessMessage41);
            //processMessage5 = new MessageRpcProcessor(ProcessMessage5);
            //processMessage6 = new MessageRpcProcessor(ProcessMessage6);
            //processMessage7 = new MessageRpcProcessor(ProcessMessage7);
            //processMessage8 = new MessageRpcProcessor(ProcessMessage8);
            //processMessage9 = new MessageRpcProcessor(ProcessMessage9);
            //processMessageCleanup = new MessageRpcProcessor(ProcessMessageCleanup);
            processMessageNonCleanupError = new MessageRpcErrorHandler(ProcessMessageNonCleanupError);
            processMessageCleanupError    = new MessageRpcErrorHandler(ProcessMessageCleanupError);
        }
Пример #7
0
 internal void SetUnhandled(DispatchOperationRuntime operation)
 {
     unhandled = operation;
 }
Пример #8
0
        private Task DispatchAsyncCore(RequestContext request, IChannel channel, EndpointDispatcher endpointDispatcher, CancellationToken token)
        {
            var dispatchRuntime = endpointDispatcher.DispatchRuntime;
            //EndpointDispatcher endpoint = dispatchRuntime.EndpointDispatcher;
            //bool releasedPump = false;

            ServiceChannel serviceChannel     = null;
            var            sessionIdleManager = channel.GetProperty <ServiceChannel.SessionIdleManager>();
            IChannelBinder binder             = null;

            if (channel is IReplyChannel)
            {
                var rcbinder = channel.GetProperty <ReplyChannelBinder>();
                rcbinder.Init(channel as IReplyChannel, BaseAddress);
                binder = rcbinder;
            }
            else if (channel is IDuplexSessionChannel)
            {
                var dcbinder = channel.GetProperty <DuplexChannelBinder>();
                dcbinder.Init(channel as IDuplexSessionChannel, _requestReplyCorrelator, BaseAddress);
                binder = dcbinder;
            }

            serviceChannel = new ServiceChannel(
                binder,
                endpointDispatcher,
                Binding,
                sessionIdleManager.UseIfNeeded(binder, Binding.ReceiveTimeout));

            Message message = request.RequestMessage;
            DispatchOperationRuntime operation = dispatchRuntime.GetOperation(ref message);

            if (operation == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "No DispatchOperationRuntime found to process message.")));
            }

            // TODO: Wire in session open notification
            //if (shouldRejectMessageWithOnOpenActionHeader && message.Headers.Action == OperationDescription.SessionOpenedAction)
            //{
            //    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.SFxNoEndpointMatchingAddressForConnectionOpeningMessage, message.Headers.Action, "Open")));
            //}

            // TODO: Session lifetime
            //if (operation.IsTerminating && requestInfo.HasSession)
            //{
            //    isChannelTerminated = true;
            //}

            // TODO: Fix up whatever semantics OperationContext places on a host being passed
            var currentOperationContext = new OperationContext(request, message, serviceChannel, /*host*/ null);

            currentOperationContext.EndpointDispatcher = endpointDispatcher;

            var existingInstanceContext = dispatchRuntime.InstanceContextProvider.GetExistingInstanceContext(request.RequestMessage, serviceChannel.Proxy as IContextChannel);
            // TODO: Investigate consequences of cleanThread parameter
            MessageRpc rpc = new MessageRpc(request, message, operation, serviceChannel, /*host*/ null,
                                            /*cleanThread*/ true, currentOperationContext, existingInstanceContext /*, eventTraceActivity*/);

            return(operation.Parent.DispatchAsync(ref rpc, /*hasOperationContextBeenSet*/ false));
            // TODO : Fix error handling
            //catch (Exception e)
            //{
            //    if (Fx.IsFatal(e))
            //    {
            //        throw;
            //    }
            //    return HandleError(e, request, channel);
            //}
        }
Пример #9
0
        // Similar to DispatchAndReleasePump on Desktop
        internal async Task DispatchAsyncCore(RequestContext request, RequestInfo requestInfo, bool cleanThread, OperationContext currentOperationContext)
        {
            ServiceChannel     channel  = requestInfo.Channel;
            EndpointDispatcher endpoint = requestInfo.Endpoint;

            try
            {
                DispatchRuntime dispatchBehavior = requestInfo.DispatchRuntime;

                if (channel == null || dispatchBehavior == null)
                {
                    Fx.Assert("System.ServiceModel.Dispatcher.ChannelHandler.Dispatch(): (channel == null || dispatchBehavior == null)");
                }

                Message message = request.RequestMessage;
                DispatchOperationRuntime operation = dispatchBehavior.GetOperation(ref message);
                if (operation == null)
                {
                    Fx.Assert("ChannelHandler.Dispatch (operation == null)");
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException("No DispatchOperationRuntime found to process message."));
                }

                if (_shouldRejectMessageWithOnOpenActionHeader && message.Headers.Action == OperationDescription.SessionOpenedAction)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.SFxNoEndpointMatchingAddressForConnectionOpeningMessage, message.Headers.Action, "Open")));
                }

                if (operation.IsTerminating && _hasSession)
                {
                    _isChannelTerminated = true;
                }

                bool hasOperationContextBeenSet;
                if (currentOperationContext != null)
                {
                    hasOperationContextBeenSet = true;
                    currentOperationContext.ReInit(request, message, channel);
                }
                else
                {
                    hasOperationContextBeenSet = false;
                    currentOperationContext    = new OperationContext(request, message, channel, null);
                }

                if (currentOperationContext.EndpointDispatcher == null && _serviceDispatcher != null)
                {
                    currentOperationContext.EndpointDispatcher = endpoint;
                }

                MessageRpc rpc = new MessageRpc(request, message, operation, channel, _host,
                                                this, cleanThread, currentOperationContext, requestInfo.ExistingInstanceContext);

                // passing responsibility for call throttle to MessageRpc
                // (MessageRpc implicitly owns this throttle once it's created)
                requestInfo.ChannelHandlerOwnsCallThrottle = false;
                // explicitly passing responsibility for instance throttle to MessageRpc
                rpc.MessageRpcOwnsInstanceContextThrottle             = requestInfo.ChannelHandlerOwnsInstanceContextThrottle;
                requestInfo.ChannelHandlerOwnsInstanceContextThrottle = false;

                // These need to happen before Dispatch but after accessing any ChannelHandler
                // state, because we go multi-threaded after this until we reacquire pump mutex.

                await operation.Parent.DispatchAsync(rpc, hasOperationContextBeenSet);
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }

                await HandleErrorAsync(e, request, requestInfo, channel);
            }
        }
Пример #10
0
        internal MessageRpc(RequestContext requestContext, Message request, DispatchOperationRuntime operation,
                            ServiceChannel channel, ServiceHostBase host, ChannelHandler channelHandler, bool cleanThread,
                            OperationContext operationContext, InstanceContext instanceContext /*, EventTraceActivity eventTraceActivity*/)
        {
            Fx.Assert((operationContext != null), "correwcf.Dispatcher.MessageRpc.MessageRpc(), operationContext == null");
            // TODO: ChannelHandler supplied an ErrorHandler, need to supply this some other way.
            //Fx.Assert(channelHandler != null, "System.ServiceModel.Dispatcher.MessageRpc.MessageRpc(), channelHandler == null");

            //this.Activity = null;
            //this.EventTraceActivity = eventTraceActivity;
            AsyncResult               = null;
            TaskResult                = null;
            CanSendReply              = true;
            Channel                   = channel;
            this.channelHandler       = channelHandler;
            Correlation               = EmptyArray.Allocate(operation.Parent.CorrelationCount);
            DidDeserializeRequestBody = false;
            Error              = null;
            ErrorProcessor     = null;
            FaultInfo          = new ErrorHandlerFaultInfo(request.Version.Addressing.DefaultFaultAction);
            HasSecurityContext = false;
            Host                            = host;
            Instance                        = null;
            AsyncProcessor                  = null;
            NotUnderstoodHeaders            = null;
            Operation                       = operation;
            OperationContext                = operationContext;
            paused                          = false;
            ParametersDisposed              = false;
            Request                         = request;
            RequestContext                  = requestContext;
            RequestContextThrewOnReply      = false;
            SuccessfullySendReply           = false;
            RequestVersion                  = request.Version;
            Reply                           = null;
            ReplyTimeoutHelper              = new TimeoutHelper();
            SecurityContext                 = null;
            InstanceContext                 = instanceContext;
            SuccessfullyBoundInstance       = false;
            SuccessfullyIncrementedActivity = false;
            SuccessfullyLockedInstance      = false;
            switchedThreads                 = !cleanThread;
            //this.transaction = null;
            InputParameters            = null;
            OutputParameters           = null;
            ReturnParameter            = null;
            isInstanceContextSingleton = InstanceContextProviderBase.IsProviderSingleton(Channel.DispatchRuntime.InstanceContextProvider);
            invokeContinueGate         = null;

            if (!operation.IsOneWay && !operation.Parent.ManualAddressing)
            {
                RequestID   = request.Headers.MessageId;
                ReplyToInfo = new RequestReplyCorrelator.ReplyToInfo(request);
            }
            else
            {
                RequestID   = null;
                ReplyToInfo = new RequestReplyCorrelator.ReplyToInfo();
            }

            //if (DiagnosticUtility.ShouldUseActivity)
            //{
            //    this.Activity = TraceUtility.ExtractActivity(this.Request);
            //}

            //if (DiagnosticUtility.ShouldUseActivity || TraceUtility.ShouldPropagateActivity)
            //{
            //    this.ResponseActivityId = ActivityIdHeader.ExtractActivityId(this.Request);
            //}
            //else
            //{
            ResponseActivityId = Guid.Empty;
            //}

            //if (this.EventTraceActivity == null && FxTrace.Trace.IsEnd2EndActivityTracingEnabled)
            //{
            //    if (this.Request != null)
            //    {
            //        this.EventTraceActivity = EventTraceActivityHelper.TryExtractActivity(this.Request, true);
            //    }
            //}
        }
Пример #11
0
 internal void Add(string name, DispatchOperationRuntime operation)
 {
     _map.Add(name, operation);
 }