< Summary

Line coverage
23%
Covered lines: 32
Uncovered lines: 105
Coverable lines: 137
Total lines: 237
Line coverage: 23.3%
Branch coverage
8%
Covered branches: 8
Total branches: 90
Branch coverage: 8.8%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\HttpMethod.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.CodeAnalysis;
 5using System.Net.Http.QPack;
 6
 7namespace System.Net.Http
 8{
 9    public partial class HttpMethod : IEquatable<HttpMethod>
 10    {
 11        private readonly string _method;
 12        private int _hashcode;
 13
 214        public static HttpMethod Get { get; } = new("GET", H3StaticTable.MethodGet);
 115        public static HttpMethod Put { get; } = new("PUT", H3StaticTable.MethodPut);
 116        public static HttpMethod Post { get; } = new("POST", H3StaticTable.MethodPost);
 117        public static HttpMethod Delete { get; } = new("DELETE", H3StaticTable.MethodDelete);
 118        public static HttpMethod Head { get; } = new("HEAD", H3StaticTable.MethodHead);
 119        public static HttpMethod Options { get; } = new("OPTIONS", H3StaticTable.MethodOptions);
 120        public static HttpMethod Trace { get; } = new("TRACE", http3StaticTableIndex: -1);
 121        public static HttpMethod Patch { get; } = new("PATCH", http3StaticTableIndex: -1);
 22
 23        /// <summary>Gets the HTTP QUERY protocol method.</summary>
 24        /// <value>The HTTP QUERY method.</value>
 125        public static HttpMethod Query { get; } = new("QUERY", http3StaticTableIndex: -1);
 26
 27        /// <summary>Gets the HTTP CONNECT protocol method.</summary>
 28        /// <value>The HTTP CONNECT method.</value>
 129        public static HttpMethod Connect { get; } = new("CONNECT", H3StaticTable.MethodConnect);
 30
 031        public string Method => _method;
 32
 033        public HttpMethod(string method)
 034        {
 035            ArgumentException.ThrowIfNullOrWhiteSpace(method);
 036            if (!HttpRuleParser.IsToken(method))
 037            {
 038                throw new FormatException(SR.net_http_httpmethod_format_error);
 39            }
 40
 041            _method = method;
 042            Initialize(method);
 043        }
 44
 1045        private HttpMethod(string method, int http3StaticTableIndex)
 1046        {
 1047            _method = method;
 1048            Initialize(http3StaticTableIndex);
 1049        }
 50
 51        // SocketsHttpHandler-specific implementation has extra init logic.
 52        partial void Initialize(int http3Index);
 53        partial void Initialize(string method);
 54
 55        public bool Equals([NotNullWhen(true)] HttpMethod? other) =>
 056            other is not null &&
 057            string.Equals(_method, other._method, StringComparison.OrdinalIgnoreCase);
 58
 59        public override bool Equals([NotNullWhen(true)] object? obj) =>
 060            obj is HttpMethod method &&
 061            Equals(method);
 62
 63        public override int GetHashCode()
 064        {
 065            if (_hashcode == 0)
 066            {
 067                _hashcode = StringComparer.OrdinalIgnoreCase.GetHashCode(_method);
 068            }
 69
 070            return _hashcode;
 071        }
 72
 073        public override string ToString() => _method;
 74
 75        public static bool operator ==(HttpMethod? left, HttpMethod? right) =>
 076            left is null || right is null
 077                ? ReferenceEquals(left, right)
 078                : left.Equals(right);
 79
 80        public static bool operator !=(HttpMethod? left, HttpMethod? right) =>
 081            !(left == right);
 82
 83        /// <summary>Parses the provided <paramref name="method"/> into an <see cref="HttpMethod"/> instance.</summary>
 84        /// <param name="method">The method to parse.</param>
 85        /// <returns>An <see cref="HttpMethod"/> instance for the provided <paramref name="method"/>.</returns>
 86        /// <remarks>
 87        /// This method may return a singleton instance for known methods; for example, it may return <see cref="Get"/>
 88        /// if "GET" is specified. The parsing is performed in a case-insensitive manner, so it may also return <see cre
 89        /// if "get" is specified. For unknown methods, a new <see cref="HttpMethod"/> instance is returned, with the
 90        /// same validation being performed as by the <see cref="HttpMethod(string)"/> constructor.
 91        /// </remarks>
 92        public static HttpMethod Parse(ReadOnlySpan<char> method) =>
 093            GetKnownMethod(method) ??
 094            new HttpMethod(method.ToString());
 95
 96        internal static HttpMethod? GetKnownMethod(ReadOnlySpan<char> method)
 097        {
 098            if (method.Length >= 3) // 3 == smallest known method
 099            {
 0100                HttpMethod? match = (method[0] | 0x20) switch
 0101                {
 0102                    'c' => Connect,
 0103                    'd' => Delete,
 0104                    'g' => Get,
 0105                    'h' => Head,
 0106                    'o' => Options,
 0107                    'p' => method.Length switch
 0108                    {
 0109                        3 => Put,
 0110                        4 => Post,
 0111                        _ => Patch,
 0112                    },
 0113                    'q' => Query,
 0114                    't' => Trace,
 0115                    _ => null,
 0116                };
 117
 0118                if (match is not null &&
 0119                    method.Equals(match._method, StringComparison.OrdinalIgnoreCase))
 0120                {
 0121                    return match;
 122                }
 0123            }
 124
 0125            return null;
 0126        }
 127    }
 128}

D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\HttpMethod.SocketsHttpHandler.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.Net.Http.HPack;
 6using System.Net.Http.QPack;
 7using System.Text;
 8
 9namespace System.Net.Http
 10{
 11    public partial class HttpMethod
 12    {
 13        private byte[]? _http1EncodedBytes;
 14        private byte[]? _http2EncodedBytes;
 15        private byte[]? _http3EncodedBytes;
 16        private int _http3Index;
 17
 818        internal bool MustHaveRequestBody { get; private set; }
 119        internal bool IsConnect { get; private set; }
 120        internal bool IsHead { get; private set; }
 21
 22        partial void Initialize(string method)
 023        {
 024            Initialize(GetKnownMethod(method)?._http3Index ?? 0);
 025        }
 26
 27        partial void Initialize(int http3Index)
 1028        {
 1029            _http3Index = http3Index;
 30
 1031            if (http3Index == H3StaticTable.MethodConnect)
 132            {
 133                IsConnect = true;
 134            }
 935            else if (http3Index == H3StaticTable.MethodHead)
 136            {
 137                IsHead = true;
 138            }
 39            else
 840            {
 841                MustHaveRequestBody = http3Index is not (H3StaticTable.MethodGet or H3StaticTable.MethodOptions or H3Sta
 842            }
 1043        }
 44
 045        internal byte[] Http1EncodedBytes => _http1EncodedBytes ?? CreateHttp1EncodedBytes();
 046        internal byte[] Http2EncodedBytes => _http2EncodedBytes ?? CreateHttp2EncodedBytes();
 047        internal byte[] Http3EncodedBytes => _http3EncodedBytes ?? CreateHttp3EncodedBytes();
 48
 49        private byte[] CreateHttp1EncodedBytes()
 050        {
 051            HttpMethod? knownMethod = GetKnownMethod(Method);
 052            byte[]? bytes = knownMethod?._http1EncodedBytes;
 53
 054            if (bytes is null)
 055            {
 056                Debug.Assert(Ascii.IsValid(Method));
 57
 058                string method = knownMethod?.Method ?? Method;
 059                bytes = new byte[method.Length + 1];
 060                Ascii.FromUtf16(method, bytes, out _);
 061                bytes[^1] = (byte)' ';
 62
 063                knownMethod?._http1EncodedBytes = bytes;
 064            }
 65
 066            _http1EncodedBytes = bytes;
 067            return bytes;
 068        }
 69
 70        private byte[] CreateHttp2EncodedBytes()
 071        {
 072            HttpMethod? knownMethod = GetKnownMethod(Method);
 073            byte[]? bytes = knownMethod?._http2EncodedBytes;
 74
 075            if (bytes is null)
 076            {
 077                bytes = _http3Index switch
 078                {
 079                    H3StaticTable.MethodGet => [0x80 | H2StaticTable.MethodGet],
 080                    H3StaticTable.MethodPost => [0x80 | H2StaticTable.MethodPost],
 081                    _ => HPackEncoder.EncodeLiteralHeaderFieldWithoutIndexingToAllocatedArray(H2StaticTable.MethodGet, k
 082                };
 83
 084                knownMethod?._http2EncodedBytes = bytes;
 085            }
 86
 087            _http2EncodedBytes = bytes;
 088            return bytes;
 089        }
 90
 91        private byte[] CreateHttp3EncodedBytes()
 092        {
 093            HttpMethod? knownMethod = GetKnownMethod(Method);
 094            byte[]? bytes = knownMethod?._http3EncodedBytes;
 95
 096            if (bytes is null)
 097            {
 098                bytes = _http3Index > 0
 099                    ? QPackEncoder.EncodeStaticIndexedHeaderFieldToArray(_http3Index)
 0100                    : QPackEncoder.EncodeLiteralHeaderFieldWithStaticNameReferenceToArray(H3StaticTable.MethodGet, known
 101
 0102                knownMethod?._http3EncodedBytes = bytes;
 0103            }
 104
 0105            _http3EncodedBytes = bytes;
 0106            return bytes;
 0107        }
 108    }
 109}