Пример #1
0
        bool PrepareAndAddressReply(ref MessageRpc rpc)
        {
            bool canSendReply = true;

            if (!manualAddressing)
            {
                if (!object.ReferenceEquals(rpc.RequestID, null))
                {
                    RequestReplyCorrelator.PrepareReply(rpc.Reply, rpc.RequestID);
                }

                if (!rpc.Channel.HasSession)
                {
                    canSendReply = RequestReplyCorrelator.AddressReply(rpc.Reply, rpc.ReplyToInfo);
                }
            }

            AddMessageProperties(rpc.Reply, rpc.OperationContext, rpc.Channel);
            //if (FxTrace.Trace.IsEnd2EndActivityTracingEnabled && rpc.EventTraceActivity != null)
            //{
            //    rpc.Reply.Properties[EventTraceActivity.Name] = rpc.EventTraceActivity;
            //}

            return(canSendReply);
        }
        void PrepareRequest(Message message)
        {
            RequestReplyCorrelator.PrepareRequest(message);
            if (this.requiresManualReplyAddressing)
            {
                if (this.localAddress != null)
                {
                    message.Headers.ReplyTo = this.LocalAddress;
                }
                else
                {
                    message.Headers.ReplyTo = EndpointAddress.AnonymousAddress;
                }
            }

            if (this.webHeaderCollection != null && this.webHeaderCollection.Count > 0)
            {
                object prop = null;
                HttpRequestMessageProperty rmp = null;
                if (message.Properties.TryGetValue(HttpRequestMessageProperty.Name, out prop))
                {
                    rmp = prop as HttpRequestMessageProperty;
                }
                else
                {
                    rmp = new HttpRequestMessageProperty();
                    message.Properties.Add(HttpRequestMessageProperty.Name, rmp);
                }

                if (rmp != null && rmp.Headers != null)
                {
                    rmp.Headers.Add(this.webHeaderCollection);
                }
            }
        }
Пример #3
0
        void DeleteTimedoutRequestsFromCorrelator()
        {
            ICorrelatorKey[] array = null;
            if (timedOutRequests != null && timedOutRequests.Count > 0)
            {
                lock (ThisLock)
                {
                    if (timedOutRequests != null && timedOutRequests.Count > 0)
                    {
                        array            = timedOutRequests.ToArray();
                        timedOutRequests = null;
                    }
                }
            }

            // Remove requests from the correlator since the channel might be either faulting, aborting or closing
            // We are not going to get a reply for these timed out requests. If they are not removed from the correlator, this will cause a leak.
            // This operation does not have to be under the lock
            if (array != null && array.Length > 0)
            {
                RequestReplyCorrelator requestReplyCorrelator = correlator as RequestReplyCorrelator;
                if (requestReplyCorrelator != null)
                {
                    foreach (ICorrelatorKey request in array)
                    {
                        requestReplyCorrelator.RemoveRequest(request);
                    }
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Prepares a reply
        /// </summary>
        /// <param name="request">The request context to prepare</param>
        /// <param name="reply">The reply to prepare</param>
        /// <returns>True if channel is open and prepared reply should be sent; otherwise false.</returns>
        bool PrepareReply(RequestContext request, Message reply)
        {
            // Ensure we only reply once (we may hit the same error multiple times)
            if (_replied == request)
            {
                return(false);
            }

            _replied = request;

            bool canSendReply = true;

            Message requestMessage = null;

            try
            {
                requestMessage = request.RequestMessage;
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }
                // swallow it
            }
            if (!object.ReferenceEquals(requestMessage, null))
            {
                UniqueId requestID = null;
                try
                {
                    requestID = requestMessage.Headers.MessageId;
                }
                catch (MessageHeaderException)
                {
                    // swallow it - we don't need to correlate the reply if the MessageId header is bad
                }
                if (!object.ReferenceEquals(requestID, null) && !_isManualAddressing)
                {
                    RequestReplyCorrelator.PrepareReply(reply, requestID);
                }
                if (!_hasSession && !_isManualAddressing)
                {
                    try
                    {
                        canSendReply = RequestReplyCorrelator.AddressReply(reply, requestMessage);
                    }
                    catch (MessageHeaderException)
                    {
                        // swallow it - we don't need to address the reply if the FaultTo header is bad
                    }
                }
            }

            // ObjectDisposeException can happen
            // if the channel is closed in a different
            // thread. 99% this check will avoid false
            // exceptions.
            return(IsOpen && canSendReply);
        }
Пример #5
0
        protected void OnReceive(Message message)
        {
            DebugTrace.TraceEnter(this, "OnReceive");
            if ((message != null) && !this.tokenResolver.FaultInSupportingToken(message))
            {
                if (DebugTrace.Verbose)
                {
                    DebugTrace.Trace(TraceLevel.Verbose, "Failed to fault in SCT for supporting token signature");
                }
                Fault invalidParameters = Faults.Version(this.protocolVersion).InvalidParameters;
                if (message.Headers.MessageId != null)
                {
                    if (DebugTrace.Verbose)
                    {
                        DebugTrace.Trace(TraceLevel.Verbose, "Attempting to send {0} fault", invalidParameters.Code.Name);
                    }
                    Message reply = Library.CreateFaultMessage(message.Headers.MessageId, message.Version, invalidParameters);
                    RequestReplyCorrelator.AddressReply(reply, new RequestReplyCorrelator.ReplyToInfo(message));
                    SendSecurityHeader header = SupportingTokenChannel <TChannel> .SecurityStandardsManager.CreateSendSecurityHeader(reply, string.Empty, true, false, SecurityAlgorithmSuite.Default, MessageDirection.Output);

                    header.RequireMessageProtection = false;
                    header.AddTimestamp(SecurityProtocolFactory.defaultTimestampValidityDuration);
                    reply = header.SetupExecution();
                    this.TrySendFaultReply(reply);
                }
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(Microsoft.Transactions.SR.GetString("SupportingTokenSignatureExpected")));
            }
            DebugTrace.TraceLeave(this, "OnReceive");
        }
Пример #6
0
 private void PrepareRequest(Message nextMessage, RequestSecurityToken rst)
 {
     if ((rst != null) && !rst.IsReadOnly)
     {
         rst.Message = nextMessage;
     }
     RequestReplyCorrelator.PrepareRequest(nextMessage);
     if (this.RequiresManualReplyAddressing)
     {
         nextMessage.Headers.ReplyTo = EndpointAddress.AnonymousAddress;
     }
 }
 void PrepareRequest(Message nextMessage, RequestSecurityToken rst)
 {
     if (rst != null && !rst.IsReadOnly)
     {
         rst.Message = nextMessage;
     }
     RequestReplyCorrelator.PrepareRequest(nextMessage);
     if (this.RequiresManualReplyAddressing)
     {
         // if we are on HTTP, we need to explicitly add a reply-to header for interop
         nextMessage.Headers.ReplyTo = EndpointAddress.AnonymousAddress;
     }
 }
Пример #8
0
        public async Task <Message> RequestAsync(Message message, CancellationToken token)
        {
            RequestReplyCorrelator.PrepareRequest(message);
            AsyncDuplexRequest duplexRequest = new AsyncDuplexRequest(this);

            lock (ThisLock)
            {
                RequestStarting(message, duplexRequest);
            }

            await _channel.SendAsync(message, token);

            return(await duplexRequest.WaitForReplyAsync(token));
        }
Пример #9
0
 private void PrepareRequest(Message message)
 {
     RequestReplyCorrelator.PrepareRequest(message);
     if (this.requiresManualReplyAddressing)
     {
         if (this.localAddress != null)
         {
             message.Headers.ReplyTo = this.LocalAddress;
         }
         else
         {
             message.Headers.ReplyTo = EndpointAddress.AnonymousAddress;
         }
     }
 }
Пример #10
0
        void AbortRequests()
        {
            IDuplexRequest[] array = null;
            lock (ThisLock)
            {
                if (requests != null)
                {
                    array = requests.ToArray();

                    foreach (IDuplexRequest request in array)
                    {
                        request.Abort();
                    }
                }
                requests       = null;
                requestAborted = true;
            }

            // Remove requests from the correlator since the channel might be either faulting or aborting,
            // We are not going to get a reply for these requests. If they are not removed from the correlator, this will cause a leak.
            // This operation does not have to be under the lock
            if (array != null && array.Length > 0)
            {
                RequestReplyCorrelator requestReplyCorrelator = correlator as RequestReplyCorrelator;
                if (requestReplyCorrelator != null)
                {
                    foreach (IDuplexRequest request in array)
                    {
                        ICorrelatorKey keyedRequest = request as ICorrelatorKey;
                        if (keyedRequest != null)
                        {
                            requestReplyCorrelator.RemoveRequest(keyedRequest);
                        }
                    }
                }
            }

            //if there are any timed out requests, delete it from the correlator table
            DeleteTimedoutRequestsFromCorrelator();
        }
        public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state)
        {
            IAsyncResult       result2;
            bool               flag    = false;
            AsyncDuplexRequest request = null;

            try
            {
                RequestReplyCorrelator.PrepareRequest(message);
                request = new AsyncDuplexRequest(message, this, timeout, callback, state);
                lock (this.ThisLock)
                {
                    this.RequestStarting(message, request);
                }
                IAsyncResult sendResult = this.channel.BeginSend(message, timeout, Fx.ThunkCallback(new AsyncCallback(this.SendCallback)), request);
                if (sendResult.CompletedSynchronously)
                {
                    request.FinishedSend(sendResult, true);
                }
                this.EnsurePumping();
                flag    = true;
                result2 = request;
            }
            finally
            {
                lock (this.ThisLock)
                {
                    if (flag)
                    {
                        request.EnableCompletion();
                    }
                    else
                    {
                        this.RequestCompleting(request);
                    }
                }
            }
            return(result2);
        }
Пример #12
0
        public async Task <Message> RequestAsync(Message message, CancellationToken token)
        {
            AsyncDuplexRequest duplexRequest = null;
            bool optimized = false;

            RequestReplyCorrelator.PrepareRequest(message);

            lock (ThisLock)
            {
                if (!Pumping)
                {
                    optimized       = true;
                    syncPumpEnabled = true;
                }

                if (!optimized)
                {
                    duplexRequest = new AsyncDuplexRequest(this);
                }

                RequestStarting(message, duplexRequest);
            }

            if (optimized)
            {
                UniqueId messageId = message.Headers.MessageId;

                try
                {
                    await channel.SendAsync(message, token);

                    //if (DiagnosticUtility.ShouldUseActivity &&
                    //    ServiceModelActivity.Current != null &&
                    //    ServiceModelActivity.Current.ActivityType == ActivityType.ProcessAction)
                    //{
                    //    ServiceModelActivity.Current.Suspend();
                    //}

                    for (;;)
                    {
                        var result = await channel.TryReceiveAsync(token);

                        if (!result.Success)
                        {
                            // TODO: Derive CancellationToken to attach timeout
                            throw TraceUtility.ThrowHelperError(GetReceiveTimeoutException(TimeSpan.Zero), message);
                        }

                        if (result.Result == null)
                        {
                            AbortRequests();
                            return(null);
                        }

                        if (result.Result.Headers.RelatesTo == messageId)
                        {
                            ThrowIfInvalidReplyIdentity(result.Result);
                            return(result.Result);
                        }
                        else if (!HandleRequestAsReply(result.Result))
                        {
                            // SFx drops a message here
                            //if (DiagnosticUtility.ShouldTraceInformation)
                            //{
                            //    EndpointDispatcher dispatcher = null;
                            //    if (this.ChannelHandler != null && this.ChannelHandler.Channel != null)
                            //    {
                            //        dispatcher = this.ChannelHandler.Channel.EndpointDispatcher;
                            //    }
                            //    TraceUtility.TraceDroppedMessage(reply, dispatcher);
                            //}
                            result.Result.Close();
                        }
                    }
                }
                finally
                {
                    lock (ThisLock)
                    {
                        RequestCompleting(null);
                        syncPumpEnabled = false;
                        if (pending > 0)
                        {
                            EnsurePumping();
                        }
                    }
                }
            }
            else
            {
                await channel.SendAsync(message, token);

                EnsurePumping();
                return(await duplexRequest.WaitForReplyAsync(token));
            }
        }
        public Message Request(Message message, TimeSpan timeout)
        {
            SyncDuplexRequest request = null;
            bool flag = false;

            RequestReplyCorrelator.PrepareRequest(message);
            lock (this.ThisLock)
            {
                if (!this.Pumping)
                {
                    flag = true;
                    this.syncPumpEnabled = true;
                }
                if (!flag)
                {
                    request = new SyncDuplexRequest(this);
                }
                this.RequestStarting(message, request);
            }
            if (flag)
            {
                TimeoutHelper helper    = new TimeoutHelper(timeout);
                UniqueId      messageId = message.Headers.MessageId;
                try
                {
                    this.channel.Send(message, helper.RemainingTime());
                    if ((DiagnosticUtility.ShouldUseActivity && (ServiceModelActivity.Current != null)) && (ServiceModelActivity.Current.ActivityType == ActivityType.ProcessAction))
                    {
                        ServiceModelActivity.Current.Suspend();
                    }
                    while (true)
                    {
                        Message  message2;
                        TimeSpan span = helper.RemainingTime();
                        if (!this.channel.TryReceive(span, out message2))
                        {
                            throw TraceUtility.ThrowHelperError(this.GetReceiveTimeoutException(timeout), message);
                        }
                        if (message2 == null)
                        {
                            this.AbortRequests();
                            return(null);
                        }
                        if (message2.Headers.RelatesTo == messageId)
                        {
                            this.ThrowIfInvalidReplyIdentity(message2);
                            return(message2);
                        }
                        if (!this.HandleRequestAsReply(message2))
                        {
                            if (DiagnosticUtility.ShouldTraceInformation)
                            {
                                EndpointDispatcher endpointDispatcher = null;
                                if ((this.ChannelHandler != null) && (this.ChannelHandler.Channel != null))
                                {
                                    endpointDispatcher = this.ChannelHandler.Channel.EndpointDispatcher;
                                }
                                TraceUtility.TraceDroppedMessage(message2, endpointDispatcher);
                            }
                            message2.Close();
                        }
                    }
                }
                finally
                {
                    lock (this.ThisLock)
                    {
                        this.RequestCompleting(null);
                        this.syncPumpEnabled = false;
                        if (this.pending > 0)
                        {
                            this.EnsurePumping();
                        }
                    }
                }
            }
            TimeoutHelper helper2 = new TimeoutHelper(timeout);

            this.channel.Send(message, helper2.RemainingTime());
            this.EnsurePumping();
            return(request.WaitForReply(helper2.RemainingTime()));
        }