< Summary

Line coverage
100%
Covered lines: 30
Uncovered lines: 0
Coverable lines: 30
Total lines: 72
Line coverage: 100%
Branch coverage
100%
Covered branches: 14
Total branches: 14
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.cctor()100%11100%
.ctor(...)100%11100%
TryParseValue(...)100%1414100%

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductInfoHeaderParser.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.Diagnostics.CodeAnalysis;
 6
 7namespace System.Net.Http.Headers
 8{
 9    // Don't derive from BaseHeaderParser since empty values are not supported. After a ' ' separator a valid value
 10    // must follow. Also leading separators are not allowed.
 11    internal sealed class ProductInfoHeaderParser : HttpHeaderParser
 12    {
 13        // Unlike most other headers, User-Agent and Server use whitespace as separators
 14        private const string separator = " ";
 15
 116        internal static readonly ProductInfoHeaderParser SingleValueParser = new ProductInfoHeaderParser(false);
 117        internal static readonly ProductInfoHeaderParser MultipleValueParser = new ProductInfoHeaderParser(true);
 18
 19        private ProductInfoHeaderParser(bool supportsMultipleValues)
 220            : base(supportsMultipleValues, separator)
 221        {
 222        }
 23
 24        public override bool TryParseValue([NotNullWhen(true)] string? value, object? storeValue, ref int index, [NotNul
 1715425        {
 1715426            parsedValue = null;
 27
 1715428            if (string.IsNullOrEmpty(value) || (index == value.Length))
 1029            {
 1030                return false;
 31            }
 32
 33            // Skip leading whitespace
 1714434            int current = index + HttpRuleParser.GetWhitespaceLength(value, index);
 35
 1714436            if (current == value.Length)
 237            {
 238                return false; // whitespace-only values are not valid
 39            }
 40
 1714241            int length = ProductInfoHeaderValue.GetProductInfoLength(value, current, out ProductInfoHeaderValue? result)
 42
 1714243            if (length == 0)
 45644            {
 45645                return false;
 46            }
 47
 48            // GetProductInfoLength() already skipped trailing whitespace. No need to do it here again.
 1668649            current += length;
 50
 51            // If we have more values, make sure we saw a whitespace before. Values like "product/1.0(comment)" are
 52            // invalid since there must be a whitespace between the product and the comment value.
 1668653            if (current < value.Length)
 1636854            {
 55                // Note that for \r\n to be a valid whitespace, it must be followed by a space/tab. I.e. it's enough if
 56                // we check whether the char before the next value is space/tab.
 1636857                char lastSeparatorChar = value[current - 1];
 1636858                if ((lastSeparatorChar != ' ') && (lastSeparatorChar != '\t'))
 28059                {
 28060                    return false;
 61                }
 1608862            }
 63
 64            // Separators for "User-Agent" and "Server" headers are whitespace. This is different from most other header
 65            // where comma/semicolon is used as separator.
 1640666            index = current;
 1640667            parsedValue = result!;
 1640668            return true;
 1715469        }
 70    }
 71}
 72