< Summary

Class:Azure.Core.HttpMessageSanitizer
Assembly:Azure.Security.KeyVault.Certificates
File(s):C:\Git\azure-sdk-for-net\sdk\core\Azure.Core\src\Shared\HttpMessageSanitizer.cs
Covered lines:10
Uncovered lines:42
Coverable lines:52
Total lines:134
Line coverage:19.2% (10 of 52)
Covered branches:4
Total branches:34
Branch coverage:11.7% (4 of 34)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
.ctor(...)-100%100%
SanitizeHeader(...)-100%100%
SanitizeUrl(...)-0%0%

File(s)

C:\Git\azure-sdk-for-net\sdk\core\Azure.Core\src\Shared\HttpMessageSanitizer.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System;
 5using System.Collections.Generic;
 6using System.Text;
 7using System.Linq;
 8
 9namespace Azure.Core
 10{
 11    internal class HttpMessageSanitizer
 12    {
 13        private const string LogAllValue = "*";
 14        private readonly bool _logAllHeaders;
 15        private readonly bool _logFullQueries;
 16        private readonly string[] _allowedQueryParameters;
 17        private readonly string _redactedPlaceholder;
 18        private readonly HashSet<string> _allowedHeaders;
 19
 17220        public HttpMessageSanitizer(string[] allowedQueryParameters, string[] allowedHeaders, string redactedPlaceholder
 21        {
 17222            _logAllHeaders = allowedHeaders.Contains(LogAllValue);
 17223            _logFullQueries = allowedQueryParameters.Contains(LogAllValue);
 24
 17225            _allowedQueryParameters = allowedQueryParameters;
 17226            _redactedPlaceholder = redactedPlaceholder;
 17227            _allowedHeaders = new HashSet<string>(allowedHeaders, StringComparer.InvariantCultureIgnoreCase);
 17228        }
 29
 30        public string SanitizeHeader(string name, string value)
 31        {
 6032            if (_logAllHeaders || _allowedHeaders.Contains(name))
 33            {
 4034                return value;
 35            }
 36
 2037            return _redactedPlaceholder;
 38        }
 39
 40        public string SanitizeUrl(string url)
 41        {
 042            if (_logFullQueries)
 43            {
 044                return url;
 45            }
 46
 047            int indexOfQuerySeparator = url.IndexOf('?');
 048            if (indexOfQuerySeparator == -1)
 49            {
 050                return url;
 51            }
 52
 053            StringBuilder stringBuilder = new StringBuilder(url.Length);
 054            stringBuilder.Append(url, 0, indexOfQuerySeparator);
 55
 056            string query = url.Substring(indexOfQuerySeparator);
 57
 058            int queryIndex = 1;
 059            stringBuilder.Append('?');
 60
 61            do
 62            {
 063                int endOfParameterValue = query.IndexOf('&', queryIndex);
 064                int endOfParameterName = query.IndexOf('=', queryIndex);
 065                bool noValue = false;
 66
 67                // Check if we have parameter without value
 068                if ((endOfParameterValue == -1 && endOfParameterName == -1) ||
 069                    (endOfParameterValue != -1 && (endOfParameterName == -1 || endOfParameterName > endOfParameterValue)
 70                {
 071                    endOfParameterName = endOfParameterValue;
 072                    noValue = true;
 73                }
 74
 075                if (endOfParameterName == -1)
 76                {
 077                    endOfParameterName = query.Length;
 78                }
 79
 080                if (endOfParameterValue == -1)
 81                {
 082                    endOfParameterValue = query.Length;
 83                }
 84                else
 85                {
 86                    // include the separator
 087                    endOfParameterValue++;
 88                }
 89
 090                ReadOnlySpan<char> parameterName = query.AsSpan(queryIndex, endOfParameterName - queryIndex);
 91
 092                bool isAllowed = false;
 093                foreach (string name in _allowedQueryParameters)
 94                {
 095                    if (parameterName.Equals(name.AsSpan(), StringComparison.OrdinalIgnoreCase))
 96                    {
 097                        isAllowed = true;
 098                        break;
 99                    }
 100                }
 101
 0102                int valueLength = endOfParameterValue - queryIndex;
 0103                int nameLength = endOfParameterName - queryIndex;
 104
 0105                if (isAllowed)
 106                {
 0107                    stringBuilder.Append(query, queryIndex, valueLength);
 108                }
 109                else
 110                {
 0111                    if (noValue)
 112                    {
 0113                        stringBuilder.Append(query, queryIndex, valueLength);
 114                    }
 115                    else
 116                    {
 0117                        stringBuilder.Append(query, queryIndex, nameLength);
 0118                        stringBuilder.Append("=");
 0119                        stringBuilder.Append(_redactedPlaceholder);
 0120                        if (query[endOfParameterValue - 1] == '&')
 121                        {
 0122                            stringBuilder.Append("&");
 123                        }
 124                    }
 125                }
 126
 0127                queryIndex += valueLength;
 128
 0129            } while (queryIndex < query.Length);
 130
 0131            return stringBuilder.ToString();
 132        }
 133    }
 134}