< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Channels.WebSocketHelper
Assembly: CoreWCF.Http
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Http/src/CoreWCF/Channels/WebSocketHelper.cs
Line coverage
23%
Covered lines: 16
Uncovered lines: 53
Coverable lines: 69
Total lines: 208
Line coverage: 23.1%
Branch coverage
19%
Covered branches: 9
Total branches: 46
Branch coverage: 19.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Http/src/CoreWCF/Channels/WebSocketHelper.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.Collections.Generic;
 6using System.Globalization;
 7using System.Net.WebSockets;
 8using System.Threading.Tasks;
 9using CoreWCF.Runtime;
 10
 11namespace CoreWCF.Channels
 12{
 13    internal static class WebSocketHelper
 14    {
 15        internal const int OperationNotStarted = 0;
 16        internal const int OperationFinished = 1;
 17        internal const string CloseOperation = "CloseOperation";
 18        internal const string SendOperation = "SendOperation";
 19        internal const string ReceiveOperation = "ReceiveOperation";
 220        internal static readonly char[] ProtocolSeparators = new char[] { ',' };
 221        internal static readonly HashSet<char> InvalidSeparatorSet = new HashSet<char>(new char[] { '(', ')', '<', '>', 
 22        private const string SchemeWs = "ws";
 23        private const string SchemeWss = "wss";
 24
 25        internal static int GetReceiveBufferSize(long maxReceivedMessageSize)
 26        {
 3327            int effectiveMaxReceiveBufferSize = maxReceivedMessageSize <= WebSocketDefaults.BufferSize ? (int)maxReceive
 3328            return Math.Max(WebSocketDefaults.MinReceiveBufferSize, effectiveMaxReceiveBufferSize);
 29        }
 30
 31        internal static bool IsSubProtocolInvalid(string protocol, out string invalidChar)
 32        {
 33            Fx.Assert(protocol != null, "protocol should not be null");
 47334            char[] chars = protocol.ToCharArray();
 472235            for (int i = 0; i < chars.Length; i++)
 36            {
 188837                char ch = chars[i];
 188838                if (ch < 0x21 || ch > 0x7e)
 39                {
 040                    invalidChar = string.Format(CultureInfo.InvariantCulture, "[{0}]", (int)ch);
 041                    return true;
 42                }
 43
 188844                if (InvalidSeparatorSet.Contains(ch))
 45                {
 046                    invalidChar = ch.ToString();
 047                    return true;
 48                }
 49            }
 50
 47351            invalidChar = null;
 47352            return false;
 53        }
 54
 55        internal static void ThrowCorrectException(Exception ex)
 56        {
 057            throw ConvertAndTraceException(ex);
 58        }
 59
 60        internal static void ThrowCorrectException(Exception ex, TimeSpan timeout, string operation)
 61        {
 062            throw ConvertAndTraceException(ex, timeout, operation);
 63        }
 64
 65        internal static Exception ConvertAndTraceException(Exception ex)
 66        {
 067            return ConvertAndTraceException(
 068                    ex,
 069                    TimeSpan.MinValue, // this is a dummy since operation type is null, so the timespan value won't be u
 070                    null);
 71        }
 72
 73        internal static Exception ConvertAndTraceException(Exception ex, TimeSpan timeout, string operation)
 74        {
 075            if (ex is ObjectDisposedException objectDisposedException)
 76            {
 077                var communicationObjectAbortedException = new CommunicationObjectAbortedException(ex.Message, ex);
 078                Fx.Exception.AsWarning(communicationObjectAbortedException);
 079                return communicationObjectAbortedException;
 80            }
 81
 082            if (ex is AggregateException aggregationException)
 83            {
 084                Exception exception = Fx.Exception.AsError<OperationCanceledException>(aggregationException);
 085                if (exception is OperationCanceledException operationCanceledException)
 86                {
 087                    TimeoutException timeoutException = GetTimeoutException(exception, timeout, operation);
 088                    Fx.Exception.AsWarning(timeoutException);
 089                    return timeoutException;
 90                }
 91                else
 92                {
 093                    Exception communicationException = ConvertAggregateExceptionToCommunicationException(aggregationExce
 094                    if (communicationException is CommunicationObjectAbortedException)
 95                    {
 096                        Fx.Exception.AsWarning(communicationException);
 097                        return communicationException;
 98                    }
 99                    else
 100                    {
 0101                        return Fx.Exception.AsError(communicationException);
 102                    }
 103                }
 104            }
 105
 0106            if (ex is WebSocketException webSocketException)
 107            {
 0108                switch (webSocketException.WebSocketErrorCode)
 109                {
 110                    case WebSocketError.InvalidMessageType:
 111                    case WebSocketError.UnsupportedProtocol:
 112                    case WebSocketError.UnsupportedVersion:
 0113                        ex = new ProtocolException(ex.Message, ex);
 0114                        break;
 115                    default:
 0116                        ex = new CommunicationException(ex.Message, ex);
 117                        break;
 118                }
 119            }
 120
 0121            return Fx.Exception.AsError(ex);
 122        }
 123
 124        internal static Exception ConvertAggregateExceptionToCommunicationException(AggregateException ex)
 125        {
 0126            Exception exception = Fx.Exception.AsError<WebSocketException>(ex);
 0127            if (exception is WebSocketException webSocketException && webSocketException.InnerException != null)
 128            {
 129                // TODO: Find out is AspNetCore has some specific exception type they throw
 130                //HttpListenerException httpListenerException = webSocketException.InnerException as HttpListenerExcepti
 131                //if (httpListenerException != null)
 132                //{
 133                //    return HttpChannelUtilities.CreateCommunicationException(httpListenerException);
 134                //}
 135            }
 136
 0137            if (exception is ObjectDisposedException objectDisposedException)
 138            {
 0139                return new CommunicationObjectAbortedException(exception.Message, exception);
 140            }
 141
 0142            return new CommunicationException(exception.Message, exception);
 143        }
 144
 145        internal static void ThrowExceptionOnTaskFailure(Task task, TimeSpan timeout, string operation)
 146        {
 11147            if (task.IsFaulted)
 148            {
 0149                throw Fx.Exception.AsError<CommunicationException>(task.Exception);
 150            }
 11151            else if (task.IsCanceled)
 152            {
 0153                throw Fx.Exception.AsError(GetTimeoutException(null, timeout, operation));
 154            }
 11155        }
 156
 157        internal static TimeoutException GetTimeoutException(Exception innerException, TimeSpan timeout, string operatio
 158        {
 0159            string errorMsg = string.Empty;
 0160            if (operation != null)
 161            {
 162                switch (operation)
 163                {
 164                    case CloseOperation:
 0165                        errorMsg = SR.Format(SR.CloseTimedOut, timeout);
 0166                        break;
 167                    case SendOperation:
 0168                        errorMsg = SR.Format(SR.WebSocketSendTimedOut, timeout);
 0169                        break;
 170                    case ReceiveOperation:
 0171                        errorMsg = SR.Format(SR.WebSocketReceiveTimedOut, timeout);
 0172                        break;
 173                    default:
 0174                        errorMsg = SR.Format(SR.WebSocketOperationTimedOut, operation, timeout);
 175                        break;
 176                }
 177            }
 178
 0179            return innerException == null ? new TimeoutException(errorMsg) : new TimeoutException(errorMsg, innerExcepti
 180        }
 181
 182        internal static bool UseWebSocketTransport(WebSocketTransportUsage transportUsage, bool isContractDuplex)
 183        {
 71184            return transportUsage == WebSocketTransportUsage.Always
 71185                || (transportUsage == WebSocketTransportUsage.WhenDuplex && isContractDuplex);
 186        }
 187
 188        internal static Uri GetWebSocketUri(Uri httpUri)
 189        {
 190            Fx.Assert(httpUri != null, "RemoteAddress.Uri should not be null.");
 0191            UriBuilder builder = new UriBuilder(httpUri);
 192
 0193            if (Uri.UriSchemeHttp.Equals(httpUri.Scheme, StringComparison.OrdinalIgnoreCase))
 194            {
 0195                builder.Scheme = SchemeWs;
 196            }
 197            else
 198            {
 199                Fx.Assert(
 200                    Uri.UriSchemeHttps.Equals(httpUri.Scheme, StringComparison.OrdinalIgnoreCase),
 201                    "httpUri.Scheme should be http or https.");
 0202                builder.Scheme = SchemeWss;
 203            }
 204
 0205            return builder.Uri;
 206        }
 207    }
 208}