< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Channels.Framing.ServerFramingDuplexSessionMiddleware
Assembly: CoreWCF.NetFramingBase
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.NetFramingBase/src/CoreWCF/Channels/Framing/ServerFramingDuplexSessionMiddleware.cs
Line coverage
83%
Covered lines: 60
Uncovered lines: 12
Coverable lines: 72
Total lines: 192
Line coverage: 83.3%
Branch coverage
80%
Covered branches: 21
Total branches: 26
Branch coverage: 80.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)100%11100%
OnConnectedAsync()91.66%121290.62%
ValidateContentType(...)83.33%6677.77%
ProcessUpgradeRequest(...)50%4450%
UpgradeConnectionAsync()100%11100%
SetupSecurityIfNecessary(...)75%4462.5%
CreatePipelineFromStream(...)100%11100%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.NetFramingBase/src/CoreWCF/Channels/Framing/ServerFramingDuplexSessionMiddleware.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.Buffers;
 6using System.IO;
 7using System.Threading.Tasks;
 8using CoreWCF.Configuration;
 9using CoreWCF.Runtime;
 10using Microsoft.Extensions.Logging;
 11
 12namespace CoreWCF.Channels.Framing
 13{
 14    internal class ServerFramingDuplexSessionMiddleware
 15    {
 16        private readonly HandshakeDelegate _next;
 17
 8318        public ServerFramingDuplexSessionMiddleware(HandshakeDelegate next)
 19        {
 8320            _next = next;
 8321        }
 22
 23        public async Task OnConnectedAsync(FramingConnection connection)
 24        {
 6425            bool success = false;
 26            try
 27            {
 6428                var decoder = connection.FramingDecoder as ServerSessionDecoder;
 29                Fx.Assert(decoder != null, "FramingDecoder must be non-null and an instance of ServerSessionDecoder");
 30                // first validate our content type
 6431                ValidateContentType(connection, decoder);
 32
 33                // next read any potential upgrades and finish consuming the preamble
 34                ReadOnlySequence<byte> buffer;
 735                while (true)
 36                {
 7137                    System.IO.Pipelines.ReadResult readResult = await connection.Input.ReadAsync();
 7138                    buffer = readResult.Buffer;
 7139                    if (readResult.IsCompleted)
 40                    {
 041                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(decoder.CreatePrematureEOFException())
 42                    }
 43
 22744                    while (buffer.Length > 0)
 45                    {
 22046                        int bytesDecoded = decoder.Decode(buffer);
 22047                        if (bytesDecoded > 0)
 48                        {
 8549                            buffer = buffer.Slice(bytesDecoded);
 50                        }
 51
 22052                        switch (decoder.CurrentState)
 53                        {
 54                            case ServerSessionDecoder.State.UpgradeRequest:
 755                                ProcessUpgradeRequest(connection, decoder);
 56
 57                                // accept upgrade
 758                                await connection.Output.WriteAsync(ServerSessionEncoder.UpgradeResponseBytes);
 759                                await connection.Output.FlushAsync();
 60                                //await context.Transport.Output.WriteAsync
 61                                //Connection.Write(ServerSessionEncoder.UpgradeResponseBytes, 0, ServerSessionEncoder.Up
 62
 63                                try
 64                                {
 765                                    connection.Input.AdvanceTo(buffer.Start);
 766                                    buffer = ReadOnlySequence<byte>.Empty;
 767                                    await UpgradeConnectionAsync(connection, decoder.Upgrade);
 68                                    // TODO: ChannelBinding
 69                                    //if (this.channelBindingProvider != null && this.channelBindingProvider.IsChannelBi
 70                                    //{
 71                                    //    this.SetChannelBinding(this.channelBindingProvider.GetChannelBinding(this.upgr
 72                                    //}
 73
 74                                    //this.connectionBuffer = Connection.AsyncReadBuffer;
 775                                }
 76                                catch (Exception exception)
 77                                {
 078                                    if (Fx.IsFatal(exception))
 79                                    {
 080                                        throw;
 81                                    }
 82
 83                                    // Audit Authentication Failure
 84                                    //WriteAuditFailure(upgradeAcceptor as StreamSecurityUpgradeAcceptor, exception);
 85                                    throw;
 86                                }
 87                                break;
 88
 89                            case ServerSessionDecoder.State.Start:
 6490                                SetupSecurityIfNecessary(connection);
 91                                // we've finished the preamble. Ack and continue to the next middleware.
 6492                                await connection.Output.WriteAsync(ServerSessionEncoder.AckResponseBytes);
 6493                                await connection.Output.FlushAsync();
 6494                                connection.Input.AdvanceTo(buffer.Start);
 6495                                await _next(connection);
 6396                                success = true;
 6397                                return;
 98
 99                        }
 100                    }
 101                }
 102            }
 103            finally
 104            {
 64105                if (!success)
 106                {
 1107                    connection.Abort();
 108                }
 109            }
 63110        }
 111
 112        private static void ValidateContentType(FramingConnection connection, FramingDecoder decoder)
 113        {
 64114            MessageEncoderFactory messageEncoderFactory = connection.MessageEncoderFactory;
 64115            MessageEncoder messageEncoder = messageEncoderFactory.CreateSessionEncoder();
 64116            connection.MessageEncoder = messageEncoder;
 117
 64118            if (!messageEncoder.IsContentTypeSupported(decoder.ContentType))
 119            {
 120                // TODO: Send fault response
 121                //SendFault(FramingEncodingString.ContentTypeInvalidFault, ref timeoutHelper);
 0122                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ProtocolException(SR.Format(
 0123                    SR.ContentTypeMismatch, decoder.ContentType, messageEncoder.ContentType)));
 124            }
 125
 64126            if (messageEncoder is ICompressedMessageEncoder compressedMessageEncoder && compressedMessageEncoder.Compres
 127            {
 4128                compressedMessageEncoder.SetSessionContentType(decoder.ContentType);
 129            }
 64130        }
 131
 132        private static void ProcessUpgradeRequest(FramingConnection connection, ServerSessionDecoder decoder)
 133        {
 7134            StreamUpgradeAcceptor upgradeAcceptor = connection.StreamUpgradeAcceptor;
 7135            if (upgradeAcceptor == null)
 136            {
 137                // TODO: SendFault
 138                //SendFault(FramingEncodingString.UpgradeInvalidFault, ref timeoutHelper);
 0139                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
 0140                    new ProtocolException(SR.Format(SR.UpgradeRequestToNonupgradableService, decoder.Upgrade)));
 141            }
 142
 7143            if (!upgradeAcceptor.CanUpgrade(decoder.Upgrade))
 144            {
 145                // TODO: SendFault
 146                //SendFault(FramingEncodingString.UpgradeInvalidFault, ref timeoutHelper);
 0147                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
 0148                    new ProtocolException(SR.Format(SR.UpgradeProtocolNotSupported, decoder.Upgrade)));
 149            }
 7150        }
 151
 152        public static async Task UpgradeConnectionAsync(FramingConnection connection, string contentType)
 153        {
 7154            var duplexPipeStream = new DuplexPipeStream(connection.Input, connection.Output);
 7155            connection.RawStream = duplexPipeStream;
 7156            StreamUpgradeAcceptor upgradeAcceptor = connection.StreamUpgradeAcceptor;
 7157            connection.Logger.StartStreamUpgradeAccept(upgradeAcceptor);
 7158            Stream stream = await upgradeAcceptor.AcceptUpgradeAsync(connection.RawStream);
 7159            duplexPipeStream.SetContentType(contentType);
 7160            connection.Logger.CompleteStreamUpgradeAccept(upgradeAcceptor);
 7161            CreatePipelineFromStream(connection, stream);
 7162        }
 163
 164        private static void SetupSecurityIfNecessary(FramingConnection connection)
 165        {
 64166            if (connection.StreamUpgradeAcceptor is StreamSecurityUpgradeAcceptor securityUpgradeAcceptor)
 167            {
 7168                Security.SecurityMessageProperty remoteSecurity = securityUpgradeAcceptor.GetRemoteSecurity();
 169
 7170                if (remoteSecurity == null)
 171                {
 0172                    Exception securityFailedException = new ProtocolException(
 0173                        SR.Format(SR.RemoteSecurityNotNegotiatedOnStreamUpgrade, connection.Via));
 174                    //WriteAuditFailure(securityUpgradeAcceptor, securityFailedException);
 0175                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(securityFailedException);
 176                }
 177                else
 178                {
 7179                    connection.SecurityMessageProperty = remoteSecurity;
 180                    // Audit Authentication Success
 181                    //WriteAuditEvent(securityUpgradeAcceptor, AuditLevel.Success, null);
 182                }
 183            }
 64184        }
 185
 186        private static void CreatePipelineFromStream(FramingConnection connection, Stream stream)
 187        {
 7188            var wrappedPipeline = new StreamDuplexPipe(connection.Transport, stream);
 7189            connection.Transport = wrappedPipeline;
 7190        }
 191    }
 192}