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)
        {
            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();
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        internal async Task <bool> ReadModeAsync(PipeReader inputPipe)
        {
            ReadOnlySequence <byte> buffer;

            while (true)
            {
                var readResult = await inputPipe.ReadAsync();

                if (readResult.IsCompleted)
                {
                    return(false);
                }

                buffer = readResult.Buffer;

                while (buffer.Length > 0)
                {
                    int bytesDecoded;
                    try
                    {
                        bytesDecoded = 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 (CurrentState == State.Done)
                    {
                        inputPipe.AdvanceTo(buffer.Start);
                        return(true);
                    }
                }

                inputPipe.AdvanceTo(buffer.End);
            }
        }