From af7b8780008568e43ed90ab49bb484f2650d2e42 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Thu, 11 Aug 2022 15:42:09 -0400 Subject: [PATCH 1/2] Avoid url string allocation in WebProxy.IsMatchInBypassList --- .../src/System.Net.WebProxy.csproj | 1 + .../src/System/Net/WebProxy.cs | 26 ++++++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Net.WebProxy/src/System.Net.WebProxy.csproj b/src/libraries/System.Net.WebProxy/src/System.Net.WebProxy.csproj index 980f1552ded92f..fbe0e197d113c3 100644 --- a/src/libraries/System.Net.WebProxy/src/System.Net.WebProxy.csproj +++ b/src/libraries/System.Net.WebProxy/src/System.Net.WebProxy.csproj @@ -10,6 +10,7 @@ + diff --git a/src/libraries/System.Net.WebProxy/src/System/Net/WebProxy.cs b/src/libraries/System.Net.WebProxy/src/System/Net/WebProxy.cs index f2e8b5fdbb5748..bb09924e361cec 100644 --- a/src/libraries/System.Net.WebProxy/src/System/Net/WebProxy.cs +++ b/src/libraries/System.Net.WebProxy/src/System/Net/WebProxy.cs @@ -1,7 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Buffers; using System.Collections; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.Serialization; @@ -154,16 +156,26 @@ private bool IsMatchInBypassList(Uri input) { UpdateRegexList(canThrow: false); - if (_regexBypassList != null) + if (_regexBypassList is Regex[] bypassList) { - Span stackBuffer = stackalloc char[128]; - string matchUriString = input.IsDefaultPort ? - string.Create(null, stackBuffer, $"{input.Scheme}://{input.Host}") : - string.Create(null, stackBuffer, $"{input.Scheme}://{input.Host}:{(uint)input.Port}"); + bool isDefaultPort = input.IsDefaultPort; + int lengthRequired = input.Scheme.Length + 3 + input.Host.Length; + if (isDefaultPort) + { + lengthRequired += 1 + 10; // 1 for ':' and 10 for max formatted length of a uint + } + + int charsWritten; + Span url = lengthRequired <= 256 ? stackalloc char[256] : new char[lengthRequired]; + bool formatted = isDefaultPort ? + url.TryWrite($"{input.Scheme}://{input.Host}", out charsWritten) : + url.TryWrite($"{input.Scheme}://{input.Host}:{(uint)input.Port}", out charsWritten); + Debug.Assert(formatted); + url = url.Slice(0, charsWritten); - foreach (Regex r in _regexBypassList) + foreach (Regex r in bypassList) { - if (r.IsMatch(matchUriString)) + if (r.IsMatch(url)) { return true; } From 1c9816240ac30b05c6d008cca9efef062d4c7a6f Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Thu, 11 Aug 2022 16:35:56 -0400 Subject: [PATCH 2/2] Update src/libraries/System.Net.WebProxy/src/System/Net/WebProxy.cs Co-authored-by: Miha Zupan --- src/libraries/System.Net.WebProxy/src/System/Net/WebProxy.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Net.WebProxy/src/System/Net/WebProxy.cs b/src/libraries/System.Net.WebProxy/src/System/Net/WebProxy.cs index bb09924e361cec..9460000a28e752 100644 --- a/src/libraries/System.Net.WebProxy/src/System/Net/WebProxy.cs +++ b/src/libraries/System.Net.WebProxy/src/System/Net/WebProxy.cs @@ -160,9 +160,9 @@ private bool IsMatchInBypassList(Uri input) { bool isDefaultPort = input.IsDefaultPort; int lengthRequired = input.Scheme.Length + 3 + input.Host.Length; - if (isDefaultPort) + if (!isDefaultPort) { - lengthRequired += 1 + 10; // 1 for ':' and 10 for max formatted length of a uint + lengthRequired += 1 + 5; // 1 for ':' and 5 for max formatted length of a port (16 bit value) } int charsWritten;