protected override async Task OnSendAsync(Message message, TimeSpan timeout) { this.ThrowIfDisposedOrNotOpen(); TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); // If timeout == TimeSpan.MaxValue, then we want to pass Timeout.Infinite as // SemaphoreSlim doesn't accept timeouts > Int32.MaxValue. // Using TimeoutHelper.RemainingTime() would yield a value less than TimeSpan.MaxValue // and would result in the value Int32.MaxValue so we must use the original timeout specified. if (!await _sendLock.WaitAsync(TimeoutHelper.ToMilliseconds(timeout))) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TimeoutException( SR.Format(SR.SendToViaTimedOut, Via, timeout), TimeoutHelper.CreateEnterTimedOutException(timeout))); } byte[] buffer = null; try { // check again in case the previous send faulted while we were waiting for the lock this.ThrowIfDisposedOrNotOpen(); this.ThrowIfOutputSessionClosed(); bool success = false; try { this.ApplyChannelBinding(message); var tcs = new TaskCompletionSource <bool>(this); AsyncCompletionResult completionResult; if (this.IsStreamedOutput) { completionResult = this.StartWritingStreamedMessage(message, timeoutHelper.RemainingTime(), s_onWriteComplete, this); } else { bool allowOutputBatching; ArraySegment <byte> messageData; allowOutputBatching = message.Properties.AllowOutputBatching; messageData = this.EncodeMessage(message); buffer = messageData.Array; completionResult = this.StartWritingBufferedMessage( message, messageData, allowOutputBatching, timeoutHelper.RemainingTime(), s_onWriteComplete, tcs); } if (completionResult == AsyncCompletionResult.Completed) { tcs.TrySetResult(true); } await tcs.Task; this.FinishWritingMessage(); success = true; if (TD.MessageSentByTransportIsEnabled()) { EventTraceActivity eventTraceActivity = EventTraceActivityHelper.TryExtractActivity(message); TD.MessageSentByTransport(eventTraceActivity, this.RemoteAddress.Uri.AbsoluteUri); } } finally { if (!success) { this.Fault(); } } } finally { _sendLock.Release(); } if (buffer != null) { _bufferManager.ReturnBuffer(buffer); } }
IAsyncResult BeginGetContext(bool startListening) { EventTraceActivity eventTraceActivity = null; if (FxTrace.Trace.IsEnd2EndActivityTracingEnabled) { eventTraceActivity = EventTraceActivity.GetFromThreadOrCreate(true); if (TD.HttpGetContextStartIsEnabled()) { TD.HttpGetContextStart(eventTraceActivity); } } while (true) { Exception unexpectedException = null; try { try { if (ExecutionContext.IsFlowSuppressed()) { return(this.BeginGetContextCore(eventTraceActivity)); } else { using (ExecutionContext.SuppressFlow()) { return(this.BeginGetContextCore(eventTraceActivity)); } } } catch (HttpListenerException e) { if (!this.HandleHttpException(e)) { throw; } } } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } if (startListening) { // Since we're under a call to StartListening(), just throw the exception up the stack. throw; } unexpectedException = e; } if (unexpectedException != null) { this.Fault(unexpectedException); return(null); } } }
public void Connect(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); addNeighbor.Set(); // We are trying to add a neighbor List <IAsyncResult> results = new List <IAsyncResult>(); List <WaitHandle> handles = new List <WaitHandle>(); // While we have more to endpoints try and we have connections pending and we are not connected upto ideal yet, and the maintainer is still open while (results.Count != 0 || (((nodeAddresses.Count != 0 || pendingConnectedNeighbor.Count != 0) && maintainer.IsOpen) && maintainer.ConnectedNeighborCount < wantedConnectionCount)) { try { handles.Clear(); foreach (IAsyncResult iar in results) { handles.Add(iar.AsyncWaitHandle); } handles.Add(welcomeReceived); // One of our connect requests resulted in a welcome or neighborManager was shutting down handles.Add(maintainerClosed); // One of our connect requests resulted in a welcome or neighborManager was shutting down handles.Add(addNeighbor); // Make the last waithandle the add a neighbor signal int index = WaitHandle.WaitAny(handles.ToArray(), config.ConnectTimeout, false); if (index == results.Count) // welcomeReceived was signalled { welcomeReceived.Reset(); } else if (index == results.Count + 1) // maintainerClosed was signalled { maintainerClosed.Reset(); lock (ThisLock) { nodeAddresses.Clear(); } } else if (index == results.Count + 2) // addNeighbor was signalled { // We need to open a new neighbor if (nodeAddresses.Count > 0) { if (pendingConnectedNeighbor.Count + maintainer.ConnectedNeighborCount < wantedConnectionCount) { PeerNodeAddress epr = null; lock (ThisLock) { if (nodeAddresses.Count == 0 || !maintainer.IsOpen) // nodeAddresses or maintainer is closed got updated better cycle { addNeighbor.Reset(); continue; } int index2 = random.Next() % nodeAddresses.Count; ICollection <Uri> keys = nodeAddresses.Keys; int i = 0; Uri key = null; foreach (Uri uri in keys) { if (i++ == index2) { key = uri; break; } } Fx.Assert(key != null, "key cannot be null here"); epr = nodeAddresses[key]; Fx.Assert(epr != null, "epr cannot be null here"); nodeAddresses.Remove(key); } if (maintainer.FindDuplicateNeighbor(epr) == null && pendingConnectedNeighbor.ContainsKey(GetEndpointUri(epr)) == false) { lock (ThisLock) { pendingConnectedNeighbor.Add(GetEndpointUri(epr), epr); } // If the neighborManager is not open this call is going to throw. // It throws ObjectDisposed exception. // This check merely eliminates the perf hit, this check is not strictly necessary // but cuts down the window for the ---- that will result in a throw to a miniscule level // We ---- the throw because we are closing down try { if (maintainer.IsOpen) { if (DiagnosticUtility.ShouldTraceInformation) { PeerMaintainerTraceRecord record = new PeerMaintainerTraceRecord(SR.GetString(SR.PeerMaintainerConnect, epr, this.config.MeshId)); TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.PeerMaintainerActivity, SR.GetString(SR.TraceCodePeerMaintainerActivity), record, this, null); } IAsyncResult iar = maintainer.BeginOpenNeighbor(epr, timeoutHelper.RemainingTime(), null, epr); results.Add(iar); } } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } if (DiagnosticUtility.ShouldTraceInformation) { PeerMaintainerTraceRecord record = new PeerMaintainerTraceRecord(SR.GetString(SR.PeerMaintainerConnectFailure, epr, this.config.MeshId, e.Message)); TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.PeerMaintainerActivity, SR.GetString(SR.TraceCodePeerMaintainerActivity), record, this, null); } // I need to remove the epr just began because the BeginOpen threw. // However Object Disposed can arise as a result of a ---- between PeerNode.Close() // and Connect trying to reconnect nodes. pendingConnectedNeighbor.Remove(GetEndpointUri(epr)); if (!(e is ObjectDisposedException)) { throw; } DiagnosticUtility.TraceHandledException(e, TraceEventType.Information); } } } } if (nodeAddresses.Count == 0 || pendingConnectedNeighbor.Count + maintainer.ConnectedNeighborCount == wantedConnectionCount) { addNeighbor.Reset(); } } else if (index != WaitHandle.WaitTimeout) { // We have completed this thing remove it from results IAsyncResult iar = results[index]; results.RemoveAt(index); IPeerNeighbor neighbor = null; try { // Get opened neighbor and fire NeighborOpened notification neighbor = maintainer.EndOpenNeighbor(iar); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } pendingConnectedNeighbor.Remove(GetEndpointUri((PeerNodeAddress)iar.AsyncState)); throw; } } else { //A timeout occured no connections progressed, try some more connections //This may result in more than wantedConnectionCount connections if the timeout connections were // merely being slow pendingConnectedNeighbor.Clear(); results.Clear(); addNeighbor.Set(); } } catch (CommunicationException e) { // mostly likely the endpoint could not be reached, but any channel exception means we should try another node DiagnosticUtility.TraceHandledException(e, TraceEventType.Information); addNeighbor.Set(); } catch (TimeoutException e) { if (TD.OpenTimeoutIsEnabled()) { TD.OpenTimeout(e.Message); } DiagnosticUtility.TraceHandledException(e, TraceEventType.Information); addNeighbor.Set(); } } }
void HandleCompletedAccept(IAsyncResult result) { IConnection connection = null; lock (ThisLock) { bool success = false; Exception unexpectedException = null; try { if (!isDisposed) { connection = listener.EndAccept(result); if (connection != null) { if (connections + 1 >= maxPendingConnections) { if (TD.MaxPendingConnectionsExceededIsEnabled()) { TD.MaxPendingConnectionsExceeded(SR.GetString(SR.TraceCodeMaxPendingConnectionsReached)); } if (DiagnosticUtility.ShouldTraceWarning) { TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.MaxPendingConnectionsReached, SR.GetString(SR.TraceCodeMaxPendingConnectionsReached), new StringTraceRecord("MaxPendingConnections", maxPendingConnections.ToString(System.Globalization.CultureInfo.InvariantCulture)), this, null); } } else if (TD.PendingConnectionsRatioIsEnabled()) { TD.PendingConnectionsRatio(connections + 1, maxPendingConnections); } // This is incremented after the Trace just in case the Trace throws. connections++; } } success = true; } catch (CommunicationException exception) { DiagnosticUtility.TraceHandledException(exception, TraceEventType.Information); } catch (Exception exception) { if (Fx.IsFatal(exception)) { throw; } if ((errorCallback == null) && !ExceptionHandler.HandleTransportExceptionHelper(exception)) { throw; } unexpectedException = exception; } finally { if (!success) { connection = null; } pendingAccepts--; if (pendingAccepts == 0 && TD.PendingAcceptsAtZeroIsEnabled()) { TD.PendingAcceptsAtZero(); } } if ((unexpectedException != null) && (errorCallback != null)) { errorCallback(unexpectedException); } } AcceptIfNecessary(false); if (connection != null) { callback(connection, onConnectionDequeued); } }
static void OnProcessConnection(IAsyncResult result) { if (result.CompletedSynchronously) { return; } EstablishConnectionAsyncResult thisPtr = (EstablishConnectionAsyncResult)result.AsyncState; Exception completionException = null; bool completeSelf; try { bool snapshotCollection = false; try { completeSelf = thisPtr.HandleProcessConnection(result); if (completeSelf) { snapshotCollection = true; } } catch (CommunicationException communicationException) { if (!thisPtr.newConnection) // CommunicationException is ok from our cache { DiagnosticUtility.TraceHandledException(communicationException, TraceEventType.Information); thisPtr.Cleanup(); completeSelf = thisPtr.Begin(); } else { completeSelf = true; completionException = communicationException; } } catch (TimeoutException timeoutException) { if (!thisPtr.newConnection) // TimeoutException is ok from our cache { if (TD.OpenTimeoutIsEnabled()) { TD.OpenTimeout(timeoutException.Message); } DiagnosticUtility.TraceHandledException(timeoutException, TraceEventType.Information); thisPtr.Cleanup(); completeSelf = thisPtr.Begin(); } else { completeSelf = true; completionException = timeoutException; } } if (snapshotCollection) { thisPtr.SnapshotConnection(); } } #pragma warning suppress 56500 // Microsoft, transferring exception to another thread catch (Exception e) { if (Fx.IsFatal(e)) { throw; } completeSelf = true; completionException = e; } if (completeSelf) { thisPtr.Cleanup(); thisPtr.Complete(false, completionException); } }
public IConnection EstablishConnection(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); IConnection localRawConnection = null; IConnection localUpgradedConnection = null; bool localIsConnectionFromPool = true; EventTraceActivity localEventTraceActivity = this.EventTraceActivity; if (TD.EstablishConnectionStartIsEnabled()) { TD.EstablishConnectionStart(localEventTraceActivity, this.via != null ? this.via.AbsoluteUri : string.Empty); } // first try and use a connection from our pool (and use it if we successfully receive an ACK) while (localIsConnectionFromPool) { localRawConnection = this.TakeConnection(timeoutHelper.RemainingTime()); if (localRawConnection == null) { localIsConnectionFromPool = false; } else { bool preambleSuccess = false; try { localUpgradedConnection = AcceptPooledConnection(localRawConnection, ref timeoutHelper); preambleSuccess = true; break; } catch (CommunicationException e) { DiagnosticUtility.TraceHandledException(e, TraceEventType.Information); // CommmunicationException is ok since it was a cached connection of unknown state } catch (TimeoutException e) { if (TD.OpenTimeoutIsEnabled()) { TD.OpenTimeout(e.Message); } DiagnosticUtility.TraceHandledException(e, TraceEventType.Information); // ditto for TimeoutException } finally { if (!preambleSuccess) { if (TD.ConnectionPoolPreambleFailedIsEnabled()) { TD.ConnectionPoolPreambleFailed(localEventTraceActivity); } if (DiagnosticUtility.ShouldTraceInformation) { TraceUtility.TraceEvent( TraceEventType.Information, TraceCode.FailedAcceptFromPool, SR.GetString( SR.TraceCodeFailedAcceptFromPool, timeoutHelper.RemainingTime())); } // This cannot throw TimeoutException since isConnectionStillGood is false (doesn't attempt a Close). this.connectionPool.ReturnConnection(connectionKey, localRawConnection, false, TimeSpan.Zero); } } } } // if there isn't anything in the pool, we need to use a new connection if (!localIsConnectionFromPool) { bool success = false; TimeSpan connectTimeout = timeoutHelper.RemainingTime(); try { try { localRawConnection = this.connectionInitiator.Connect(this.via, connectTimeout); } catch (TimeoutException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateNewConnectionTimeoutException( connectTimeout, e)); } this.connectionInitiator = null; localUpgradedConnection = AcceptPooledConnection(localRawConnection, ref timeoutHelper); success = true; } finally { if (!success) { connectionKey = null; if (localRawConnection != null) { localRawConnection.Abort(); } } } } SnapshotConnection(localUpgradedConnection, localRawConnection, localIsConnectionFromPool); if (TD.EstablishConnectionStopIsEnabled()) { TD.EstablishConnectionStop(localEventTraceActivity); } return(localUpgradedConnection); }
private async Task <WebSocket> CreateWebSocketWithFactoryAsync(X509Certificate2 certificate, TimeoutHelper timeoutHelper) { Contract.Assert(_connectionFactory != null, "Invalid call: CreateWebSocketWithFactory."); if (TD.WebSocketCreateClientWebSocketWithFactoryIsEnabled()) { TD.WebSocketCreateClientWebSocketWithFactory(EventTraceActivity, _connectionFactory.GetType().FullName); } // Create the client WebSocket with the factory. WebSocket ws; try { if (certificate != null) { throw ExceptionHelper.PlatformNotSupported("client certificates not supported yet"); } var headers = new WebHeaderCollection(); headers[WebSocketTransportSettings.SoapContentTypeHeader] = _channelFactory.WebSocketSoapContentType; if (_channelFactory.MessageEncoderFactory is BinaryMessageEncoderFactory) { headers[WebSocketTransportSettings.BinaryEncoderTransferModeHeader] = _channelFactory.TransferMode.ToString(); } var credentials = _channelFactory.GetCredentials(); ws = await _connectionFactory.CreateWebSocketAsync(Via, headers, credentials, WebSocketSettings.Clone(), timeoutHelper); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } throw FxTrace.Exception.AsError(new InvalidOperationException(SR.Format(SR.ClientWebSocketFactory_CreateWebSocketFailed, _connectionFactory.GetType().Name), e)); } // The returned WebSocket should be valid (non-null), in an opened state and with the same SubProtocol that we requested. if (ws == null) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.Format(SR.ClientWebSocketFactory_InvalidWebSocket, _connectionFactory.GetType().Name))); } if (ws.State != WebSocketState.Open) { ws.Dispose(); throw FxTrace.Exception.AsError(new InvalidOperationException(SR.Format(SR.ClientWebSocketFactory_InvalidWebSocket, _connectionFactory.GetType().Name))); } string requested = WebSocketSettings.SubProtocol; string obtained = ws.SubProtocol; if (!(requested == null ? string.IsNullOrWhiteSpace(obtained) : requested.Equals(obtained, StringComparison.OrdinalIgnoreCase))) { ws.Dispose(); throw FxTrace.Exception.AsError(new InvalidOperationException(SR.Format(SR.ClientWebSocketFactory_InvalidSubProtocol, _connectionFactory.GetType().Name, obtained, requested))); } return(ws); }
protected internal override async Task OnOpenAsync(TimeSpan timeout) { TimeoutHelper helper = new TimeoutHelper(timeout); bool success = false; try { if (TD.WebSocketConnectionRequestSendStartIsEnabled()) { TD.WebSocketConnectionRequestSendStart( EventTraceActivity, RemoteAddress != null ? RemoteAddress.ToString() : string.Empty); } ChannelParameterCollection channelParameterCollection = new ChannelParameterCollection(); if (HttpChannelFactory <IDuplexSessionChannel> .MapIdentity(this.RemoteAddress, _channelFactory.AuthenticationScheme)) { lock (ThisLock) { _cleanupIdentity = HttpTransportSecurityHelpers.AddIdentityMapping(Via, RemoteAddress); } } X509Certificate2 clientCertificate = null; HttpsChannelFactory <IDuplexSessionChannel> httpsChannelFactory = _channelFactory as HttpsChannelFactory <IDuplexSessionChannel>; if (httpsChannelFactory != null && httpsChannelFactory.RequireClientCertificate) { var certificateProvider = httpsChannelFactory.CreateAndOpenCertificateTokenProvider(RemoteAddress, Via, channelParameterCollection, helper.RemainingTime()); var clientCertificateToken = httpsChannelFactory.GetCertificateSecurityToken(certificateProvider, RemoteAddress, Via, channelParameterCollection, ref helper); var x509Token = (X509SecurityToken)clientCertificateToken.Token; clientCertificate = x509Token.Certificate; } try { WebSocket = await CreateWebSocketWithFactoryAsync(clientCertificate, helper); } finally { if (WebSocket != null && _cleanupStarted) { WebSocket.Abort(); CommunicationObjectAbortedException communicationObjectAbortedException = new CommunicationObjectAbortedException( new WebSocketException(WebSocketError.ConnectionClosedPrematurely).Message); FxTrace.Exception.AsWarning(communicationObjectAbortedException); throw communicationObjectAbortedException; } } bool inputUseStreaming = TransferModeHelper.IsResponseStreamed(TransferMode); SetMessageSource(new WebSocketMessageSource( this, WebSocket, inputUseStreaming, this)); success = true; if (TD.WebSocketConnectionRequestSendStopIsEnabled()) { TD.WebSocketConnectionRequestSendStop( EventTraceActivity, WebSocket != null ? WebSocket.GetHashCode() : -1); } } catch (WebSocketException ex) { if (TD.WebSocketConnectionFailedIsEnabled()) { TD.WebSocketConnectionFailed(EventTraceActivity, ex.Message); } TryConvertAndThrow(ex); } finally { CleanupTokenProviders(); if (!success) { CleanupOnError(); } } }
protected override void SendHttpPipelineResponse() { this.WaitTransportIntegrationHandlerTask(this.defaultSendTimeout); HttpResponseMessage response = this.transportIntegrationHandlerTask.Result; // HttpResponseMessage equals to null means that the pipeline is already cancelled. // We should aborte the connection immediately in this case. if (response == null) { this.cancellationTokenSource.Cancel(); } else { if (response.StatusCode == HttpStatusCode.SwitchingProtocols) { string protocol = null; if (response.Headers.Contains(WebSocketHelper.SecWebSocketProtocol)) { foreach (string headerValue in response.Headers.GetValues(WebSocketHelper.SecWebSocketProtocol)) { protocol = headerValue; break; } response.Headers.Remove(WebSocketHelper.SecWebSocketProtocol); } // Remove unnecessary properties from HttpRequestMessage if (response.RequestMessage != null) { HttpPipeline.RemoveHttpPipeline(response.RequestMessage); response.RequestMessage.Properties.Remove(RemoteEndpointMessageProperty.Name); } // CSDMain 255817: There's a race condition that the channel could be dequeued and pipeline could be closed before the // Listener.CreateWebSocketChannelAndEnqueue call finishes. In this case, we are actually calling BeginGetContext twice, thus // cause the memory leak. this.isShortCutResponse = false; bool channelEnqueued; try { channelEnqueued = this.HttpRequestContext.Listener.CreateWebSocketChannelAndEnqueue(this.HttpRequestContext, this, response, protocol, this.dequeuedCallback); } catch (Exception ex) { if (!Fx.IsFatal(ex)) { if (TD.WebSocketConnectionFailedIsEnabled()) { TD.WebSocketConnectionFailed(this.EventTraceActivity, ex.Message); } this.HttpRequestContext.SendResponseAndClose(HttpStatusCode.InternalServerError); } throw; } this.isShortCutResponse = !channelEnqueued; if (!channelEnqueued) { if (TD.WebSocketConnectionDeclinedIsEnabled()) { TD.WebSocketConnectionDeclined(this.EventTraceActivity, HttpStatusCode.ServiceUnavailable.ToString()); } this.httpRequestContext.SendResponseAndClose(HttpStatusCode.ServiceUnavailable); } } else { if (TD.WebSocketConnectionDeclinedIsEnabled()) { TD.WebSocketConnectionDeclined(this.EventTraceActivity, response.StatusCode.ToString()); } this.SendAndClose(response); } } }
/// <summary> /// Check if trace definition is enabled /// Event description ID=4801, Level=verbose, Channel=Debug /// </summary> internal static bool ByteStreamMessageDecodingStartIsEnabled() { return(FxTrace.ShouldTraceVerbose && TD.IsEtwEventEnabled(1)); }
/// <summary> /// Check if trace definition is enabled /// Event description ID=4800, Level=Warning, Channel=debug /// </summary> internal static bool MaxPendingMessagesTotalSizeReachedIsEnabled() { return(FxTrace.ShouldTraceWarning && (FxTrace.ShouldTraceWarningToTraceSource || TD.IsEtwEventEnabled(0))); }
public override ArraySegment <byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset) { if (message == null) { throw FxTrace.Exception.ArgumentNull("message"); } if (bufferManager == null) { throw FxTrace.Exception.ArgumentNull("bufferManager"); } if (maxMessageSize < 0) { throw FxTrace.Exception.ArgumentOutOfRange("maxMessageSize", maxMessageSize, SR.ArgumentOutOfMinRange(0)); } if (messageOffset < 0) { throw FxTrace.Exception.ArgumentOutOfRange("messageOffset", messageOffset, SR.ArgumentOutOfMinRange(0)); } EventTraceActivity eventTraceActivity = null; if (TD.ByteStreamMessageEncodingStartIsEnabled()) { eventTraceActivity = EventTraceActivityHelper.TryExtractActivity(message); TD.ByteStreamMessageEncodingStart(eventTraceActivity); } ThrowIfMismatchedMessageVersion(message); message.Properties.Encoder = this; ArraySegment <byte> messageBuffer; int size; using (BufferManagerOutputStream stream = new BufferManagerOutputStream(maxSentMessageSizeExceededResourceString, 0, maxMessageSize, bufferManager)) { stream.Skip(messageOffset); using (XmlWriter writer = new XmlByteStreamWriter(stream, true)) { message.WriteMessage(writer); writer.Flush(); byte[] bytes = stream.ToArray(out size); messageBuffer = new ArraySegment <byte>(bytes, messageOffset, size - messageOffset); } } if (SMTD.MessageWrittenByEncoderIsEnabled()) { SMTD.MessageWrittenByEncoder( eventTraceActivity ?? EventTraceActivityHelper.TryExtractActivity(message), messageBuffer.Count, this); } if (MessageLogger.LogMessagesAtTransportLevel) { // DevDiv#486728 // Don't pass in a buffer manager to avoid returning 'messageBuffer" to the bufferManager twice. ByteStreamBufferedMessageData messageData = new ByteStreamBufferedMessageData(messageBuffer, null); using (XmlReader reader = new XmlBufferedByteStreamReader(messageData, this.quotas)) { MessageLogger.LogMessage(ref message, reader, MessageLoggingSource.TransportSend); } } return(messageBuffer); }
void OnConnectionModeKnownCore(ConnectionModeReader modeReader, bool isCached) { lock (ThisLock) { if (isDisposed) { return; } this.connectionReaders.Remove(modeReader); } bool closeReader = true; try { FramingMode framingMode; try { framingMode = modeReader.GetConnectionMode(); } catch (CommunicationException exception) { TraceEventType eventType = modeReader.Connection.ExceptionEventType; DiagnosticUtility.TraceHandledException(exception, eventType); return; } catch (TimeoutException exception) { if (!isCached) { exception = new TimeoutException(SR.GetString(SR.ChannelInitializationTimeout, this.channelInitializationTimeout), exception); System.ServiceModel.Dispatcher.ErrorBehavior.ThrowAndCatch(exception); } if (TD.ChannelInitializationTimeoutIsEnabled()) { TD.ChannelInitializationTimeout(SR.GetString(SR.ChannelInitializationTimeout, this.channelInitializationTimeout)); } TraceEventType eventType = modeReader.Connection.ExceptionEventType; DiagnosticUtility.TraceHandledException(exception, eventType); return; } switch (framingMode) { case FramingMode.Duplex: OnDuplexConnection(modeReader.Connection, modeReader.ConnectionDequeuedCallback, modeReader.StreamPosition, modeReader.BufferOffset, modeReader.BufferSize, modeReader.GetRemainingTimeout()); break; case FramingMode.Singleton: OnSingletonConnection(modeReader.Connection, modeReader.ConnectionDequeuedCallback, modeReader.StreamPosition, modeReader.BufferOffset, modeReader.BufferSize, modeReader.GetRemainingTimeout()); break; default: { Exception inner = new InvalidDataException(SR.GetString( SR.FramingModeNotSupported, framingMode)); Exception exception = new ProtocolException(inner.Message, inner); FramingEncodingString.AddFaultString(exception, FramingEncodingString.UnsupportedModeFault); System.ServiceModel.Dispatcher.ErrorBehavior.ThrowAndCatch(exception); return; } } closeReader = false; } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } if (!ExceptionHandler.HandleTransportExceptionHelper(e)) { throw; } // containment -- the reader is aborted, no need for additional containment } finally { if (closeReader) { modeReader.Dispose(); } } }