private bool DecodeBytes(FramingConnection connection, ref ReadOnlySequence <byte> buffer) { var decoder = connection.FramingDecoder as ServerSingletonDecoder; Fx.Assert(decoder != null, "FramingDecoder must be a non-null ServerSingletonDecoder"); while (!connection.EOF && buffer.Length > 0) { int bytesRead = decoder.Decode(buffer); if (bytesRead > 0) { buffer = buffer.Slice(bytesRead); } switch (decoder.CurrentState) { case ServerSingletonDecoder.State.EnvelopeStart: // we're at the envelope return(true); case ServerSingletonDecoder.State.End: connection.EOF = true; return(false); } } return(false); }
public async Task OnConnectedAsync(FramingConnection connection) { var be = connection.ServiceDispatcher.Binding.CreateBindingElements(); var tbe = be.Find <TransportBindingElement>(); ITransportFactorySettings settings = new NetFramingTransportSettings { CloseTimeout = connection.ServiceDispatcher.Binding.CloseTimeout, OpenTimeout = connection.ServiceDispatcher.Binding.OpenTimeout, ReceiveTimeout = connection.ServiceDispatcher.Binding.ReceiveTimeout, SendTimeout = connection.ServiceDispatcher.Binding.SendTimeout, ManualAddressing = tbe.ManualAddressing, BufferManager = connection.BufferManager, MaxReceivedMessageSize = tbe.MaxReceivedMessageSize, MessageEncoderFactory = connection.MessageEncoderFactory }; var scope = _servicesScopeFactory.CreateScope(); var channel = new ServerFramingDuplexSessionChannel(connection, settings, false, _servicesScopeFactory.CreateScope().ServiceProvider); await channel.OpenAsync(); var decoder = connection.ServerSessionDecoder; var serviceDispatcher = connection.ServiceDispatcher; while (true) { Message message = await ReceiveMessageAsync(connection); if (message == null) { return; // No more messages } // TODO: Create a correctly timing out ct await serviceDispatcher.DispatchAsync(new DuplexRequestContext(channel, message, connection.ServiceDispatcher.Binding), channel, CancellationToken.None); } }
private async Task EnsureChannelAsync(FramingConnection connection) { if (_replyChannel == null) { using (await _lock.TakeLockAsync()) { if (_replyChannel == null) { var be = connection.ServiceDispatcher.Binding.CreateBindingElements(); var tbe = be.Find <TransportBindingElement>(); ITransportFactorySettings settings = new NetFramingTransportSettings { CloseTimeout = connection.ServiceDispatcher.Binding.CloseTimeout, OpenTimeout = connection.ServiceDispatcher.Binding.OpenTimeout, ReceiveTimeout = connection.ServiceDispatcher.Binding.ReceiveTimeout, SendTimeout = connection.ServiceDispatcher.Binding.SendTimeout, ManualAddressing = tbe.ManualAddressing, BufferManager = connection.BufferManager, MaxReceivedMessageSize = tbe.MaxReceivedMessageSize, MessageEncoderFactory = connection.MessageEncoderFactory }; _replyChannel = new ConnectionOrientedTransportReplyChannel(settings, null, _servicesScopeFactory.CreateScope().ServiceProvider); _channelDispatcher = await connection.ServiceDispatcher.CreateServiceChannelDispatcherAsync(_replyChannel); } } } }
public async Task OnConnectedAsync(FramingConnection connection) { var inputPipe = connection.Input; var modeDecoder = new ServerModeDecoder(); try { await modeDecoder.ReadModeAsync(inputPipe); } catch (CommunicationException e) { // see if we need to send back a framing fault string framingFault; if (FramingEncodingString.TryGetFaultString(e, out framingFault)) { // TODO: Timeouts await connection.SendFaultAsync(framingFault, Timeout.InfiniteTimeSpan /*GetRemainingTimeout()*/, ConnectionOrientedTransportDefaults.MaxViaSize + ConnectionOrientedTransportDefaults.MaxContentTypeSize); } return; // Completing the returned Task causes the connection to be closed if needed and cleans everything up. } connection.FramingMode = modeDecoder.Mode; await _next(connection); // One .NET Framework, with the way that AspNetCore closes a connection, it sometimes doesn't send the // final bytes if those bytes haven't been sent yet. Delaying completeing the connection to compensate. await Task.Delay(5); // AspNetCore 2.1 doesn't close the connection. 2.2+ does so these lines can eventually be rmoved. connection.RawTransport.Input.Complete(); connection.RawTransport.Output.Complete(); }
public async Task OnConnectedAsync(FramingConnection connection) { if (!_transportSettingsCache.TryGetValue(connection.ServiceDispatcher, out ITransportFactorySettings settings)) { BindingElementCollection be = connection.ServiceDispatcher.Binding.CreateBindingElements(); TransportBindingElement tbe = be.Find <TransportBindingElement>(); settings = new NetFramingTransportSettings { CloseTimeout = connection.ServiceDispatcher.Binding.CloseTimeout, OpenTimeout = connection.ServiceDispatcher.Binding.OpenTimeout, ReceiveTimeout = connection.ServiceDispatcher.Binding.ReceiveTimeout, SendTimeout = connection.ServiceDispatcher.Binding.SendTimeout, ManualAddressing = tbe.ManualAddressing, BufferManager = connection.BufferManager, MaxReceivedMessageSize = tbe.MaxReceivedMessageSize, MessageEncoderFactory = connection.MessageEncoderFactory }; } var channel = new ServerFramingDuplexSessionChannel(connection, settings, false, _servicesScopeFactory.CreateScope().ServiceProvider); channel.ChannelDispatcher = await connection.ServiceDispatcher.CreateServiceChannelDispatcherAsync(channel); await channel.StartReceivingAsync(); }
public async Task OnConnectedAsync(FramingConnection connection) { var be = connection.ServiceDispatcher.Binding.CreateBindingElements(); var tbe = be.Find <TransportBindingElement>(); ITransportFactorySettings settings = new NetFramingTransportSettings { CloseTimeout = connection.ServiceDispatcher.Binding.CloseTimeout, OpenTimeout = connection.ServiceDispatcher.Binding.OpenTimeout, ReceiveTimeout = connection.ServiceDispatcher.Binding.ReceiveTimeout, SendTimeout = connection.ServiceDispatcher.Binding.SendTimeout, ManualAddressing = tbe.ManualAddressing, BufferManager = connection.BufferManager, MaxReceivedMessageSize = tbe.MaxReceivedMessageSize, MessageEncoderFactory = connection.MessageEncoderFactory }; var timeoutHelper = new TimeoutHelper(settings.ReceiveTimeout); var channel = new InputChannel(settings, null, _servicesScopeFactory.CreateScope().ServiceProvider); await channel.OpenAsync(); var channelDispatcher = connection.ServiceDispatcher.CreateServiceChannelDispatcher(channel); // TODO: I think that the receive timeout starts counting at the start of the preamble on .NET Framework. This implementation basically resets the timer // after the preamble has completed. This probably needs to be addressed otherwise worse case you could end up taking 2X as long to timeout. // I believe the preamble should really use the OpenTimeout but that's not how this is implemented on .NET Framework. var requestContext = (StreamedFramingRequestContext) await ReceiveRequestAsync(connection, timeoutHelper.RemainingTime()); _ = channelDispatcher.DispatchAsync(requestContext, CancellationToken.None); await requestContext.ReplySent; await Task.Delay(5); }
private void PrepareMessage(FramingConnection connection, Message message) { if (connection.SecurityMessageProperty != null) { message.Properties.Security = (SecurityMessageProperty)connection.SecurityMessageProperty.CreateCopy(); } }
public static async Task WriteMessageAsync(Message message, FramingConnection connection, bool isRequest, IDefaultCommunicationTimeouts settings, CancellationToken token) { byte[] endBytes = null; if (message != null) { MessageEncoder messageEncoder = connection.MessageEncoderFactory.Encoder; byte[] envelopeStartBytes = SingletonEncoder.EnvelopeStartBytes; bool writeStreamed; if (isRequest) { endBytes = SingletonEncoder.EnvelopeEndFramingEndBytes; writeStreamed = TransferModeHelper.IsRequestStreamed(connection.TransferMode); } else { endBytes = SingletonEncoder.EnvelopeEndBytes; writeStreamed = TransferModeHelper.IsResponseStreamed(connection.TransferMode); } if (writeStreamed) { await connection.Output.WriteAsync(envelopeStartBytes, token); Stream connectionStream = new StreamingOutputConnectionStream(connection, settings); // TODO: Determine if timeout stream is needed as StreamingOutputConnectionStream implements some timeout functionality //Stream writeTimeoutStream = new TimeoutStream(connectionStream, ref timeoutHelper); await messageEncoder.WriteMessageAsync(message, connectionStream); await connection.Output.FlushAsync(); } else { ArraySegment <byte> messageData = messageEncoder.WriteMessage(message, int.MaxValue, connection.BufferManager, envelopeStartBytes.Length + IntEncoder.MaxEncodedSize); messageData = SingletonEncoder.EncodeMessageFrame(messageData); Buffer.BlockCopy(envelopeStartBytes, 0, messageData.Array, messageData.Offset - envelopeStartBytes.Length, envelopeStartBytes.Length); await connection.Output.WriteAsync(new ArraySegment <byte>(messageData.Array, messageData.Offset - envelopeStartBytes.Length, messageData.Count + envelopeStartBytes.Length), token); await connection.Output.FlushAsync(); connection.BufferManager.ReturnBuffer(messageData.Array); } } else if (isRequest) // context handles response end bytes { endBytes = SingletonEncoder.EndBytes; } if (endBytes != null) { await connection.Output.WriteAsync(endBytes, token); await connection.Output.FlushAsync(); } }
public static async Task UpgradeConnectionAsync(FramingConnection connection) { connection.RawStream = new RawStream(connection.Input, connection.Output); var upgradeAcceptor = connection.StreamUpgradeAcceptor; var stream = await upgradeAcceptor.AcceptUpgradeAsync(connection.RawStream); CreatePipelineFromStream(connection, stream); }
public StreamedFramingRequestContext(FramingConnection connection, Message requestMessage, Stream inputStream) : base(requestMessage, connection.ServiceDispatcher.Binding.CloseTimeout, connection.ServiceDispatcher.Binding.SendTimeout) { _connection = connection; _requestMessage = requestMessage; _inputStream = inputStream; _tcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously); }
public static async Task UpgradeConnectionAsync(FramingConnection connection) { Stream stream = new Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal.RawStream(connection.Input, connection.Output); var upgradeAcceptor = connection.StreamUpgradeAcceptor; stream = await upgradeAcceptor.AcceptUpgradeAsync(stream); CreatePipelineFromStream(connection, stream); }
private void EnsureDecoderAtEof(FramingConnection connection) { var decoder = connection.ServerSessionDecoder; if (!(decoder.CurrentState == ServerSessionDecoder.State.End || decoder.CurrentState == ServerSessionDecoder.State.EnvelopeEnd)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(decoder.CreatePrematureEOFException()); } }
public SingletonInputConnectionStream(FramingConnection connection, IDefaultCommunicationTimeouts defaultTimeouts) { _connection = connection; _timeouts = defaultTimeouts; decoder = new SingletonMessageDecoder(); chunkBytesRemaining = 0; _timeoutHelper = new TimeoutHelper(_timeouts.ReceiveTimeout); }
public async Task OnConnectedAsync(FramingConnection connection) { var inputPipe = connection.Input; var modeDecoder = new ServerModeDecoder(); await modeDecoder.ReadModeAsync(inputPipe); connection.FramingMode = modeDecoder.Mode; await _next(connection); }
public async Task OnConnectedAsync(FramingConnection connection) { using (_appLifetime.ApplicationStopped.Register(() => { connection.RawTransport.Input.Complete(); connection.RawTransport.Output.Complete(); })) { IConnectionReuseHandler reuseHandler = null; do { var inputPipe = connection.Input; var modeDecoder = new ServerModeDecoder(); try { if (!await modeDecoder.ReadModeAsync(inputPipe)) { break; // Input pipe closed } } catch (CommunicationException e) { // see if we need to send back a framing fault string framingFault; if (FramingEncodingString.TryGetFaultString(e, out framingFault)) { // TODO: Timeouts await connection.SendFaultAsync(framingFault, Timeout.InfiniteTimeSpan /*GetRemainingTimeout()*/, ConnectionOrientedTransportDefaults.MaxViaSize + ConnectionOrientedTransportDefaults.MaxContentTypeSize); } return; // Completing the returned Task causes the connection to be closed if needed and cleans everything up. } connection.FramingMode = modeDecoder.Mode; await _next(connection); // Unwrap the connection. // TODO: Investigate calling Dispose on the wrapping stream to improve cleanup. nb: .NET Framework does not call Dispose. connection.Transport = connection.RawTransport; // connection.ServiceDispatcher is null until later middleware layers are executed. if (reuseHandler == null) { reuseHandler = connection.ServiceDispatcher.Binding.GetProperty <IConnectionReuseHandler>(new BindingParameterCollection()); } } while (await reuseHandler.ReuseConnectionAsync(connection, _appLifetime.ApplicationStopping)); // On .NET Framework, with the way that AspNetCore closes a connection, it sometimes doesn't send the // final bytes if those bytes haven't been sent yet. Delaying completeing the connection to compensate. await Task.Delay(5); } // AspNetCore 2.1 doesn't close the connection. 2.2+ does so these lines can eventually be removed. connection.RawTransport.Input.Complete(); connection.RawTransport.Output.Complete(); }
public RawStream(FramingConnection connection) { #if DEBUG _connection = connection; #endif _input = connection.Input; _output = connection.Output; _canRead = true; _thisLock = new object(); }
public async Task OnConnectedAsync(FramingConnection connection) { var decoder = new ServerSessionDecoder(ConnectionOrientedTransportDefaults.MaxViaSize, ConnectionOrientedTransportDefaults.MaxContentTypeSize); ReadOnlySequence <byte> buffer; while (decoder.CurrentState != ServerSessionDecoder.State.PreUpgradeStart) { var readResult = await connection.Input.ReadAsync(); buffer = readResult.Buffer; while (buffer.Length > 0) { int bytesDecoded; try { bytesDecoded = decoder.Decode(buffer); } catch (CommunicationException e) { // see if we need to send back a framing fault string framingFault; if (FramingEncodingString.TryGetFaultString(e, out framingFault)) { // TODO: Drain the rest of the data and send a fault then close the connection //byte[] drainBuffer = new byte[128]; //InitialServerConnectionReader.SendFault( // Connection, framingFault, drainBuffer, GetRemainingTimeout(), // MaxViaSize + MaxContentTypeSize); //base.Close(GetRemainingTimeout()); } throw; } if (bytesDecoded > 0) { buffer = buffer.Slice(bytesDecoded); } if (decoder.CurrentState == ServerSessionDecoder.State.PreUpgradeStart) { // We now know the Via address (which endpoint the client is connecting to). // The connection now needs to be handled by the correct endpoint which can // handle upgrades etc. break; //exit loop } } connection.Input.AdvanceTo(buffer.Start); } connection.ServerSessionDecoder = decoder; await _next(connection); }
public static async Task UpgradeConnectionAsync(FramingConnection connection, string contentType) { var duplexPipeStream = new DuplexPipeStream(connection.Input, connection.Output); connection.RawStream = duplexPipeStream; StreamUpgradeAcceptor upgradeAcceptor = connection.StreamUpgradeAcceptor; Stream stream = await upgradeAcceptor.AcceptUpgradeAsync(connection.RawStream); duplexPipeStream.SetContentType(contentType); CreatePipelineFromStream(connection, stream); }
public ServerFramingDuplexSessionChannel(FramingConnection connection, ITransportFactorySettings settings, bool exposeConnectionProperty, IServiceProvider serviceProvider) : base(connection, settings, exposeConnectionProperty) { Connection = connection; upgradeAcceptor = connection.StreamUpgradeAcceptor; _serviceProvider = serviceProvider; //if (upgradeAcceptor != null) //{ // this.channelBindingProvider = upgrade.GetProperty<IStreamUpgradeChannelBindingProvider>(); // this.upgradeAcceptor = upgrade.CreateUpgradeAcceptor(); //} }
public async Task OnConnectedAsync(FramingConnection connection) { // If the remote client aborts or the connection, AspNetCore throws an exceptions which // bubbles all the way up to here and causes a critical level event to be logged. This is a normal thing // to happen so just swallowing the exception to suppress the critical log output. try { await OnConnectedCoreAsync(connection); } catch (Microsoft.AspNetCore.Connections.ConnectionAbortedException) { } catch (Microsoft.AspNetCore.Connections.ConnectionResetException) { } catch (CoreWCF.Security.SecurityNegotiationException) { } // TODO: Work out where this needs to be caught catch (System.IO.IOException) { } // TODO: Work out where this needs to be caught }
private void PrepareMessage(FramingConnection connection, Message message) { if (connection.SecurityMessageProperty != null) { message.Properties.Security = (SecurityMessageProperty)connection.SecurityMessageProperty.CreateCopy(); } IPEndPoint remoteEndPoint = connection.RemoteEndpoint; // pipes will return null if (remoteEndPoint != null) { var remoteEndpointProperty = new RemoteEndpointMessageProperty(remoteEndPoint); message.Properties.Add(RemoteEndpointMessageProperty.Name, remoteEndpointProperty); } }
public async Task OnConnectedAsync(FramingConnection connection) { await EnsureChannelAsync(connection); // TODO: I think that the receive timeout starts counting at the start of the preamble on .NET Framework. This implementation basically resets the timer // after the preamble has completed. This probably needs to be addressed otherwise worse case you could end up taking 2X as long to timeout. // I believe the preamble should really use the OpenTimeout but that's not how this is implemented on .NET Framework. var timeoutHelper = new TimeoutHelper(((IDefaultCommunicationTimeouts)_replyChannel).ReceiveTimeout); var requestContext = await ReceiveRequestAsync(connection, timeoutHelper.RemainingTime()); await _channelDispatcher.DispatchAsync(requestContext); await requestContext.ReplySent; //await channelDispatcher.DispatchAsync(); //await requestContext.ReplySent; }
public async Task OnConnectedAsync(FramingConnection connection) { var be = connection.ServiceDispatcher.Binding.CreateBindingElements(); var tbe = be.Find <TransportBindingElement>(); ITransportFactorySettings settings = new NetFramingTransportSettings { CloseTimeout = connection.ServiceDispatcher.Binding.CloseTimeout, OpenTimeout = connection.ServiceDispatcher.Binding.OpenTimeout, ReceiveTimeout = connection.ServiceDispatcher.Binding.ReceiveTimeout, SendTimeout = connection.ServiceDispatcher.Binding.SendTimeout, ManualAddressing = tbe.ManualAddressing, BufferManager = connection.BufferManager, MaxReceivedMessageSize = tbe.MaxReceivedMessageSize, MessageEncoderFactory = connection.MessageEncoderFactory }; var channel = new ServerFramingDuplexSessionChannel(connection, settings, false, _servicesScopeFactory.CreateScope().ServiceProvider); await channel.OpenAsync(); using (_appLifetime.ApplicationStopping.Register(() => { _ = channel.CloseAsync(); })) { var channelDispatcher = connection.ServiceDispatcher.CreateServiceChannelDispatcher(channel); while (true) { Message message = await ReceiveMessageAsync(connection); if (message == null) { await channel.CloseAsync(); return; // No more messages } var requestContext = new DuplexRequestContext(channel, message, connection.ServiceDispatcher.Binding); // TODO: Create a correctly timing out ct // We don't await DispatchAsync because in a concurrent service we want to read the next request before the previous // request has finished. _ = channelDispatcher.DispatchAsync(requestContext, CancellationToken.None); // TODO: Now there's a channel dispatcher, have that handle negotiateing a Task which completes when it's time to get the next request await requestContext.OperationDispatching; } } }
private async Task <Message> ReceiveMessageAsync(FramingConnection connection) { // TODO: Apply timeouts Message message; ReadOnlySequence <byte> buffer = ReadOnlySequence <byte> .Empty; for (; ;) { var readResult = await connection.Input.ReadAsync(); if (readResult.IsCompleted || readResult.Buffer.Length == 0) { if (!readResult.IsCompleted) { connection.Input.AdvanceTo(readResult.Buffer.Start); } EnsureDecoderAtEof(connection); connection.EOF = true; } if (connection.EOF) { return(null); } buffer = readResult.Buffer; message = DecodeMessage(connection, ref buffer); connection.Input.AdvanceTo(buffer.Start); if (message != null) { PrepareMessage(connection, message); return(message); } else if (connection.EOF) // could have read the END record under DecodeMessage { return(null); } if (buffer.Length != 0) { throw Fx.AssertAndThrow("Receive: DecodeMessage() should consume the outstanding buffer or return a message."); } } }
private static void ValidateContentType(FramingConnection connection, FramingDecoder decoder) { MessageEncoderFactory messageEncoderFactory = connection.MessageEncoderFactory; MessageEncoder messageEncoder = messageEncoderFactory.CreateSessionEncoder(); connection.MessageEncoder = messageEncoder; if (!messageEncoder.IsContentTypeSupported(decoder.ContentType)) { // TODO: Send fault response //SendFault(FramingEncodingString.ContentTypeInvalidFault, ref timeoutHelper); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ProtocolException(SR.Format( SR.ContentTypeMismatch, decoder.ContentType, messageEncoder.ContentType))); } if (messageEncoder is ICompressedMessageEncoder compressedMessageEncoder && compressedMessageEncoder.CompressionEnabled) { compressedMessageEncoder.SetSessionContentType(decoder.ContentType); } }
private static void ProcessUpgradeRequest(FramingConnection connection, ServerSessionDecoder decoder) { var upgradeAcceptor = connection.StreamUpgradeAcceptor; if (upgradeAcceptor == null) { // TODO: SendFault //SendFault(FramingEncodingString.UpgradeInvalidFault, ref timeoutHelper); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ProtocolException(SR.Format(SR.UpgradeRequestToNonupgradableService, decoder.Upgrade))); } if (!upgradeAcceptor.CanUpgrade(decoder.Upgrade)) { // TODO: SendFault //SendFault(FramingEncodingString.UpgradeInvalidFault, ref timeoutHelper); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ProtocolException(SR.Format(SR.UpgradeProtocolNotSupported, decoder.Upgrade))); } }
private static void SetupSecurityIfNecessary(FramingConnection connection) { if (connection.StreamUpgradeAcceptor is StreamSecurityUpgradeAcceptor securityUpgradeAcceptor) { Security.SecurityMessageProperty remoteSecurity = securityUpgradeAcceptor.GetRemoteSecurity(); if (remoteSecurity == null) { Exception securityFailedException = new ProtocolException( SR.Format(SR.RemoteSecurityNotNegotiatedOnStreamUpgrade, connection.Via)); //WriteAuditFailure(securityUpgradeAcceptor, securityFailedException); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(securityFailedException); } else { connection.SecurityMessageProperty = remoteSecurity; // Audit Authentication Success //WriteAuditEvent(securityUpgradeAcceptor, AuditLevel.Success, null); } } }
private void PrepareMessage(FramingConnection connection, Message message) { message.Properties.Via = connection.Via; message.Properties.Security = (connection.SecurityMessageProperty != null) ? (SecurityMessageProperty)connection.SecurityMessageProperty.CreateCopy() : null; IPEndPoint remoteEndPoint = connection.RemoteEndpoint; // pipes will return null if (remoteEndPoint != null) { var remoteEndpointProperty = new RemoteEndpointMessageProperty(remoteEndPoint); message.Properties.Add(RemoteEndpointMessageProperty.Name, remoteEndpointProperty); } // TODO: ChannelBindingToken //if (this.channelBindingToken != null) //{ // ChannelBindingMessageProperty property = new ChannelBindingMessageProperty(this.channelBindingToken, false); // property.AddTo(message); // property.Dispose(); //message.Properties.Add() creates a copy... //} }
public async Task OnConnectedAsync(FramingConnection connection) { var decoder = new ServerSingletonDecoder(ConnectionOrientedTransportDefaults.MaxViaSize, ConnectionOrientedTransportDefaults.MaxContentTypeSize, connection.Logger); bool success = false; try { ReadOnlySequence <byte> buffer; while (decoder.CurrentState != ServerSingletonDecoder.State.PreUpgradeStart) { System.IO.Pipelines.ReadResult readResult = await connection.Input.ReadAsync(); buffer = readResult.Buffer; while (buffer.Length > 0) { int bytesDecoded = decoder.Decode(buffer); if (bytesDecoded > 0) { buffer = buffer.Slice(bytesDecoded); } if (decoder.CurrentState == ServerSingletonDecoder.State.PreUpgradeStart) { // We now know the Via address (which endpoint the client is connecting to). // The connection now needs to be handled by the correct endpoint which can // handle upgrades etc. break; //exit loop } } connection.Input.AdvanceTo(buffer.Start); } success = true; } catch (CommunicationException exception) { DiagnosticUtility.TraceHandledException(exception, TraceEventType.Information); } catch (OperationCanceledException exception) { //if (TD.ReceiveTimeoutIsEnabled()) //{ // TD.ReceiveTimeout(exception.Message); //} DiagnosticUtility.TraceHandledException(exception, TraceEventType.Information); } catch (TimeoutException exception) { //if (TD.ReceiveTimeoutIsEnabled()) //{ // TD.ReceiveTimeout(exception.Message); //} DiagnosticUtility.TraceHandledException(exception, TraceEventType.Information); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } if (!TransportExceptionHandler.HandleTransportExceptionHelper(e)) { throw; } // containment -- all exceptions abort the reader, no additional containment action necessary } finally { if (!success) { // TODO: On .NET Framework, this Abort call via a long winding path of plumbing will trigger a new pending Accept // as this connection establishment handshake has failed. Some back pressure mechanism needs to be implemented to // stop extra incoming connection handshakes from being started. Maybe a semaphore which is async waited at initial // incoming request and then released on completion of handshake or on an exception. It also closes the connection // so that's all that's happening here for now. Returning and completing the task will cause the connection to be closed. connection.Abort(); } } if (success) { connection.FramingDecoder = decoder; await _next(connection); } // else: // returning will close the connection if it hasn't already been. }
public override Task OnConnectedAsync(ConnectionContext context) { var connection = new FramingConnection(context); return(_handshake(connection)); }