< Summary

Information
Class: System.Net.Http.Headers.ProductInfoHeaderParser
Assembly: System.Net.Http
File(s): D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\Headers\ProductInfoHeaderParser.cs
Line coverage
100%
Covered lines: 30
Uncovered lines: 0
Coverable lines: 30
Total lines: 71
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)

D:\runner\runtime\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
 3877125        {
 3877126            parsedValue = null;
 27
 3877128            if (string.IsNullOrEmpty(value) || (index == value.Length))
 1229            {
 1230                return false;
 31            }
 32
 33            // Skip leading whitespace
 3875934            int current = index + HttpRuleParser.GetWhitespaceLength(value, index);
 35
 3875936            if (current == value.Length)
 237            {
 238                return false; // whitespace-only values are not valid
 39            }
 40
 3875741            int length = ProductInfoHeaderValue.GetProductInfoLength(value, current, out ProductInfoHeaderValue? result)
 42
 3875743            if (length == 0)
 60844            {
 60845                return false;
 46            }
 47
 48            // GetProductInfoLength() already skipped trailing whitespace. No need to do it here again.
 3814949            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.
 3814953            if (current < value.Length)
 3693154            {
 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.
 3693157                char lastSeparatorChar = value[current - 1];
 3693158                if ((lastSeparatorChar != ' ') && (lastSeparatorChar != '\t'))
 15859                {
 15860                    return false;
 61                }
 3677362            }
 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.
 3799166            index = current;
 3799167            parsedValue = result!;
 3799168            return true;
 3877169        }
 70    }
 71}