From 59f8157123fa1f1040ee525f7886861850281809 Mon Sep 17 00:00:00 2001 From: Stephan Zehetner Date: Fri, 14 Sep 2018 15:41:00 +0200 Subject: optimize Metadata.Entry normalization and validation check. Replaced Regex with custom loop, avoid string allocation if input is already lowercase. --- src/csharp/Grpc.Core/Metadata.cs | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) (limited to 'src/csharp/Grpc.Core') diff --git a/src/csharp/Grpc.Core/Metadata.cs b/src/csharp/Grpc.Core/Metadata.cs index 281952d6d4..122c1e8883 100644 --- a/src/csharp/Grpc.Core/Metadata.cs +++ b/src/csharp/Grpc.Core/Metadata.cs @@ -225,8 +225,6 @@ namespace Grpc.Core /// public class Entry { - private static readonly Regex ValidKeyRegex = new Regex("^[.a-z0-9_-]+$"); - readonly string key; readonly string value; readonly byte[] valueBytes; @@ -358,10 +356,39 @@ namespace Grpc.Core private static string NormalizeKey(string key) { - var normalized = GrpcPreconditions.CheckNotNull(key, "key").ToLowerInvariant(); - GrpcPreconditions.CheckArgument(ValidKeyRegex.IsMatch(normalized), + GrpcPreconditions.CheckNotNull(key, "key"); + + GrpcPreconditions.CheckArgument(IsValidKey(key, out bool isLowercase), "Metadata entry key not valid. Keys can only contain lowercase alphanumeric characters, underscores, hyphens and dots."); - return normalized; + if (isLowercase) + return key; + + return key.ToLowerInvariant(); + } + + private static bool IsValidKey(string input, out bool isLowercase) + { + isLowercase = true; + for (int i = 0; i < input.Length; i++) + { + char c = input[i]; + if ('a' <= c && c <= 'z' || + '0' <= c && c <= '9' || + c == '.' || + c == '_' || + c == '-' ) + continue; + + if ('A' <= c && c <= 'Z') + { + isLowercase = false; + continue; + } + + return false; + } + + return true; } /// -- cgit v1.2.3