Skip to content

Commit 7262fe1

Browse files
Avoid url string allocation in WebProxy.IsMatchInBypassList (#73807)
* Avoid url string allocation in WebProxy.IsMatchInBypassList * Update src/libraries/System.Net.WebProxy/src/System/Net/WebProxy.cs Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com> Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>
1 parent f52d8c5 commit 7262fe1

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

src/libraries/System.Net.WebProxy/src/System.Net.WebProxy.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<Compile Condition="'$(TargetPlatformIdentifier)' != 'Browser'" Include="System\Net\WebProxy.NonBrowser.cs" />
1111
</ItemGroup>
1212
<ItemGroup>
13+
<Reference Include="System.Memory" />
1314
<Reference Include="System.Net.NameResolution" />
1415
<Reference Include="System.Net.NetworkInformation" />
1516
<Reference Include="System.Net.Primitives" />

src/libraries/System.Net.WebProxy/src/System/Net/WebProxy.cs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Buffers;
45
using System.Collections;
6+
using System.Diagnostics;
57
using System.Diagnostics.CodeAnalysis;
68
using System.Globalization;
79
using System.Runtime.Serialization;
@@ -154,16 +156,26 @@ private bool IsMatchInBypassList(Uri input)
154156
{
155157
UpdateRegexList(canThrow: false);
156158

157-
if (_regexBypassList != null)
159+
if (_regexBypassList is Regex[] bypassList)
158160
{
159-
Span<char> stackBuffer = stackalloc char[128];
160-
string matchUriString = input.IsDefaultPort ?
161-
string.Create(null, stackBuffer, $"{input.Scheme}://{input.Host}") :
162-
string.Create(null, stackBuffer, $"{input.Scheme}://{input.Host}:{(uint)input.Port}");
161+
bool isDefaultPort = input.IsDefaultPort;
162+
int lengthRequired = input.Scheme.Length + 3 + input.Host.Length;
163+
if (!isDefaultPort)
164+
{
165+
lengthRequired += 1 + 5; // 1 for ':' and 5 for max formatted length of a port (16 bit value)
166+
}
167+
168+
int charsWritten;
169+
Span<char> url = lengthRequired <= 256 ? stackalloc char[256] : new char[lengthRequired];
170+
bool formatted = isDefaultPort ?
171+
url.TryWrite($"{input.Scheme}://{input.Host}", out charsWritten) :
172+
url.TryWrite($"{input.Scheme}://{input.Host}:{(uint)input.Port}", out charsWritten);
173+
Debug.Assert(formatted);
174+
url = url.Slice(0, charsWritten);
163175

164-
foreach (Regex r in _regexBypassList)
176+
foreach (Regex r in bypassList)
165177
{
166-
if (r.IsMatch(matchUriString))
178+
if (r.IsMatch(url))
167179
{
168180
return true;
169181
}

0 commit comments

Comments
 (0)