< 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
 301425        {
 301426            parsedValue = null;
 27
 301428            if (string.IsNullOrEmpty(value) || (index == value.Length))
 1229            {
 1230                return false;
 31            }
 32
 33            // Skip leading whitespace
 300234            int current = index + HttpRuleParser.GetWhitespaceLength(value, index);
 35
 300236            if (current == value.Length)
 237            {
 238                return false; // whitespace-only values are not valid
 39            }
 40
 300041            int length = ProductInfoHeaderValue.GetProductInfoLength(value, current, out ProductInfoHeaderValue? result)
 42
 300043            if (length == 0)
 43644            {
 43645                return false;
 46            }
 47
 48            // GetProductInfoLength() already skipped trailing whitespace. No need to do it here again.
 256449            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.
 256453            if (current < value.Length)
 232454            {
 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.
 232457                char lastSeparatorChar = value[current - 1];
 232458                if ((lastSeparatorChar != ' ') && (lastSeparatorChar != '\t'))
 18259                {
 18260                    return false;
 61                }
 214262            }
 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.
 238266            index = current;
 238267            parsedValue = result!;
 238268            return true;
 301469        }
 70    }
 71}