< Summary

Line coverage
0%
Covered lines: 0
Uncovered lines: 63
Coverable lines: 63
Total lines: 115
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 26
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.cctor()100%110%
.ctor(...)0%660%
.ctor(...)0%220%
.ctor(...)0%220%
Equals(...)100%110%
Equals(...)0%220%
GetHashCode()0%440%
ToString()0%10100%
op_Equality(...)100%110%
op_Inequality(...)100%110%

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Net.Security/src/System/Net/Security/SslApplicationProtocol.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.Diagnostics;
 5using System.Diagnostics.CodeAnalysis;
 6using System.Text;
 7
 8namespace System.Net.Security
 9{
 10    public readonly struct SslApplicationProtocol : IEquatable<SslApplicationProtocol>
 11    {
 012        private static readonly Encoding s_utf8 = Encoding.GetEncoding(Encoding.UTF8.CodePage, EncoderFallback.Exception
 013        private static readonly byte[] s_http3Utf8 = "h3"u8.ToArray();
 014        private static readonly byte[] s_http2Utf8 = "h2"u8.ToArray();
 015        private static readonly byte[] s_http11Utf8 = "http/1.1"u8.ToArray();
 16
 17        // Refer to IANA on ApplicationProtocols: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensio
 18        /// <summary>Defines a <see cref="SslApplicationProtocol"/> instance for HTTP 3.0.</summary>
 019        public static readonly SslApplicationProtocol Http3 = new SslApplicationProtocol(s_http3Utf8, copy: false);
 20        /// <summary>Defines a <see cref="SslApplicationProtocol"/> instance for HTTP 2.0.</summary>
 021        public static readonly SslApplicationProtocol Http2 = new SslApplicationProtocol(s_http2Utf8, copy: false);
 22        /// <summary>Defines a <see cref="SslApplicationProtocol"/> instance for HTTP 1.1.</summary>
 023        public static readonly SslApplicationProtocol Http11 = new SslApplicationProtocol(s_http11Utf8, copy: false);
 24
 25        private readonly byte[] _readOnlyProtocol;
 26
 27        internal SslApplicationProtocol(byte[] protocol, bool copy)
 028        {
 029            Debug.Assert(protocol != null);
 30
 31            // RFC 7301 states protocol size <= 255 bytes.
 032            if (protocol.Length == 0 || protocol.Length > 255)
 033            {
 034                throw new ArgumentException(SR.net_ssl_app_protocol_invalid, nameof(protocol));
 35            }
 36
 037            _readOnlyProtocol = copy ?
 038                protocol.AsSpan().ToArray() :
 039                protocol;
 040        }
 41
 42        public SslApplicationProtocol(byte[] protocol) :
 043            this(protocol ?? throw new ArgumentNullException(nameof(protocol)), copy: true)
 044        {
 045        }
 46
 47        public SslApplicationProtocol(string protocol) :
 048            this(s_utf8.GetBytes(protocol ?? throw new ArgumentNullException(nameof(protocol))), copy: false)
 049        {
 050        }
 51
 052        public ReadOnlyMemory<byte> Protocol => _readOnlyProtocol;
 53
 54        public bool Equals(SslApplicationProtocol other) =>
 055            ((ReadOnlySpan<byte>)_readOnlyProtocol).SequenceEqual(other._readOnlyProtocol);
 56
 057        public override bool Equals([NotNullWhen(true)] object? obj) => obj is SslApplicationProtocol protocol && Equals
 58
 59        public override int GetHashCode()
 060        {
 061            byte[] arr = _readOnlyProtocol;
 062            if (arr == null)
 063            {
 064                return 0;
 65            }
 66
 067            int hash = 0;
 068            for (int i = 0; i < arr.Length; i++)
 069            {
 070                hash = ((hash << 5) + hash) ^ arr[i];
 071            }
 72
 073            return hash;
 074        }
 75
 76        public override string ToString()
 077        {
 078            byte[] arr = _readOnlyProtocol;
 79            try
 080            {
 081                return
 082                    arr is null ? string.Empty :
 083                    ReferenceEquals(arr, s_http3Utf8) ? "h3" :
 084                    ReferenceEquals(arr, s_http2Utf8) ? "h2" :
 085                    ReferenceEquals(arr, s_http11Utf8) ? "http/1.1" :
 086                    s_utf8.GetString(arr);
 87            }
 088            catch
 089            {
 90                // In case of decoding errors, return the byte values as hex string.
 091                char[] byteChars = new char[arr.Length * 5];
 092                int index = 0;
 93
 094                for (int i = 0; i < byteChars.Length; i += 5)
 095                {
 096                    byte b = arr[index++];
 097                    byteChars[i] = '0';
 098                    byteChars[i + 1] = 'x';
 099                    byteChars[i + 2] = HexConverter.ToCharLower(b >> 4);
 0100                    byteChars[i + 3] = HexConverter.ToCharLower(b);
 0101                    byteChars[i + 4] = ' ';
 0102                }
 103
 0104                return new string(byteChars, 0, byteChars.Length - 1);
 105            }
 0106        }
 107
 108        public static bool operator ==(SslApplicationProtocol left, SslApplicationProtocol right) =>
 0109            left.Equals(right);
 110
 111        public static bool operator !=(SslApplicationProtocol left, SslApplicationProtocol right) =>
 0112            !(left == right);
 113    }
 114}
 115