< Summary

Information
Class: System.Net.Http.Headers.UriHeaderParser
Assembly: System.Net.Http
File(s): D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\Headers\UriHeaderParser.cs
Line coverage
92%
Covered lines: 52
Uncovered lines: 4
Coverable lines: 56
Total lines: 103
Line coverage: 92.8%
Branch coverage
90%
Covered branches: 20
Total branches: 22
Branch coverage: 90.9%
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(...)80%101080.95%
DecodeUtf8FromString(...)100%1010100%
ToString(...)100%22100%

File(s)

D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\Headers\UriHeaderParser.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;
 6using System.Diagnostics.CodeAnalysis;
 7using System.Text;
 8
 9namespace System.Net.Http.Headers
 10{
 11    // Don't derive from BaseHeaderParser since parsing is delegated to Uri.TryCreate()
 12    // which will remove leading and trailing whitespace.
 13    internal sealed class UriHeaderParser : HttpHeaderParser
 14    {
 15        private readonly UriKind _uriKind;
 16
 117        internal static readonly UriHeaderParser RelativeOrAbsoluteUriParser =
 118            new UriHeaderParser(UriKind.RelativeOrAbsolute);
 19
 20        private UriHeaderParser(UriKind uriKind)
 121            : base(false)
 122        {
 123            _uriKind = uriKind;
 124        }
 25
 26        public override bool TryParseValue([NotNullWhen(true)] string? value, object? storeValue, ref int index, [NotNul
 10027        {
 10028            parsedValue = null;
 29
 30            // Some headers support empty/null values. This one doesn't.
 10031            if (string.IsNullOrEmpty(value) || (index == value.Length))
 1632            {
 1633                return false;
 34            }
 35
 8436            string uriString = value;
 8437            if (index > 0)
 038            {
 039                uriString = value.Substring(index);
 040            }
 41
 8442            if (!Uri.TryCreate(uriString, _uriKind, out Uri? uri))
 7443            {
 44                // Some servers send the host names in Utf-8.
 7445                uriString = DecodeUtf8FromString(uriString);
 46
 7447                if (!Uri.TryCreate(uriString, _uriKind, out uri))
 7448                {
 7449                    return false;
 50                }
 051            }
 52
 1053            index = value.Length;
 1054            parsedValue = uri;
 1055            return true;
 10056        }
 57
 58        // The normal client header parser just casts bytes to chars (see GetString).
 59        // Check if those bytes were actually utf-8 instead of ASCII.
 60        // If not, just return the input value.
 61        internal static string DecodeUtf8FromString(string input)
 7462        {
 7463            if (!string.IsNullOrWhiteSpace(input))
 7464            {
 7465                int possibleUtf8Pos = input.AsSpan().IndexOfAnyExceptInRange((char)0, (char)127);
 7466                if (possibleUtf8Pos >= 0 &&
 7467                    !input.AsSpan(possibleUtf8Pos).ContainsAnyExceptInRange((char)0, (char)255))
 7068                {
 7069                    Span<byte> rawBytes = input.Length <= 256 ? stackalloc byte[input.Length] : new byte[input.Length];
 1410470                    for (int i = 0; i < input.Length; i++)
 698271                    {
 698272                        rawBytes[i] = (byte)input[i];
 698273                    }
 74
 75                    try
 7076                    {
 77                        // We don't want '?' replacement characters, just fail.
 7078                        Encoding decoder = Encoding.GetEncoding("utf-8", EncoderFallback.ExceptionFallback, DecoderFallb
 7079                        return decoder.GetString(rawBytes);
 80                    }
 14481                    catch (ArgumentException) { } // Not actually Utf-8
 4882                }
 5283            }
 84
 5285            return input;
 7486        }
 87
 88        public override string ToString(object value)
 1589        {
 1590            Debug.Assert(value is Uri);
 1591            Uri uri = (Uri)value;
 92
 1593            if (uri.IsAbsoluteUri)
 994            {
 995                return uri.AbsoluteUri;
 96            }
 97            else
 698            {
 699                return uri.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped);
 100            }
 15101        }
 102    }
 103}