diff --git a/src/libraries/System.Net.WebClient/src/System.Net.WebClient.csproj b/src/libraries/System.Net.WebClient/src/System.Net.WebClient.csproj
index 949fea2f4d407..fdbfd8f017d68 100644
--- a/src/libraries/System.Net.WebClient/src/System.Net.WebClient.csproj
+++ b/src/libraries/System.Net.WebClient/src/System.Net.WebClient.csproj
@@ -28,6 +28,7 @@
+
diff --git a/src/libraries/System.Net.WebClient/src/System/Net/WebClient.cs b/src/libraries/System.Net.WebClient/src/System/Net/WebClient.cs
index 89a8f5375e2a1..0a893f002c75f 100644
--- a/src/libraries/System.Net.WebClient/src/System/Net/WebClient.cs
+++ b/src/libraries/System.Net.WebClient/src/System/Net/WebClient.cs
@@ -1076,24 +1076,6 @@ private async void UploadBitsAsync(
}
}
- private static bool ByteArrayHasPrefix(byte[] prefix, byte[] byteArray)
- {
- if (prefix == null || byteArray == null || prefix.Length > byteArray.Length)
- {
- return false;
- }
-
- for (int i = 0; i < prefix.Length; i++)
- {
- if (prefix[i] != byteArray[i])
- {
- return false;
- }
- }
-
- return true;
- }
-
private static readonly char[] s_parseContentTypeSeparators = new char[] { ';', '=', ' ' };
private static readonly Encoding[] s_knownEncodings = { Encoding.UTF8, Encoding.UTF32, Encoding.Unicode, Encoding.BigEndianUnicode };
@@ -1147,13 +1129,12 @@ private string GetStringUsingEncoding(WebRequest request, byte[] data)
if (enc == null)
{
// UTF32 must be tested before Unicode because it's BOM is the same but longer.
- Encoding[] encodings = s_knownEncodings;
- for (int i = 0; i < encodings.Length; i++)
+ foreach (Encoding encoding in s_knownEncodings)
{
- byte[] preamble = encodings[i].GetPreamble();
- if (ByteArrayHasPrefix(preamble, data))
+ ReadOnlySpan preamble = encoding.Preamble;
+ if (data.AsSpan().StartsWith(preamble))
{
- enc = encodings[i];
+ enc = encoding;
bomLengthInData = preamble.Length;
break;
}
@@ -1166,8 +1147,8 @@ private string GetStringUsingEncoding(WebRequest request, byte[] data)
// Calculate BOM length based on encoding guess. Then check for it in the data.
if (bomLengthInData == -1)
{
- byte[] preamble = enc.GetPreamble();
- bomLengthInData = ByteArrayHasPrefix(preamble, data) ? preamble.Length : 0;
+ ReadOnlySpan preamble = enc.Preamble;
+ bomLengthInData = data.AsSpan().StartsWith(preamble) ? preamble.Length : 0;
}
// Convert byte array to string stripping off any BOM before calling Format().
@@ -1187,88 +1168,9 @@ private string MapToDefaultMethod(Uri address)
}
[return: NotNullIfNotNull(nameof(str))]
- private static string? UrlEncode(string? str)
- {
- if (str == null)
- return null;
- byte[] bytes = Encoding.UTF8.GetBytes(str);
- return Encoding.ASCII.GetString(UrlEncodeBytesToBytesInternal(bytes, 0, bytes.Length, false));
- }
-
- private static byte[] UrlEncodeBytesToBytesInternal(byte[] bytes, int offset, int count, bool alwaysCreateReturnValue)
- {
- int cSpaces = 0;
- int cUnsafe = 0;
-
- // Count them first.
- for (int i = 0; i < count; i++)
- {
- char ch = (char)bytes[offset + i];
-
- if (ch == ' ')
- {
- cSpaces++;
- }
- else if (!IsSafe(ch))
- {
- cUnsafe++;
- }
- }
-
- // If nothing to expand.
- if (!alwaysCreateReturnValue && cSpaces == 0 && cUnsafe == 0)
- return bytes;
-
- // Expand not 'safe' characters into %XX, spaces to +.
- byte[] expandedBytes = new byte[count + cUnsafe * 2];
- int pos = 0;
-
- for (int i = 0; i < count; i++)
- {
- byte b = bytes[offset + i];
- char ch = (char)b;
-
- if (IsSafe(ch))
- {
- expandedBytes[pos++] = b;
- }
- else if (ch == ' ')
- {
- expandedBytes[pos++] = (byte)'+';
- }
- else
- {
- expandedBytes[pos++] = (byte)'%';
- expandedBytes[pos++] = (byte)HexConverter.ToCharLower(b >> 4);
- expandedBytes[pos++] = (byte)HexConverter.ToCharLower(b);
- }
- }
-
- return expandedBytes;
- }
-
- private static bool IsSafe(char ch)
- {
- if (char.IsAsciiLetterOrDigit(ch))
- {
- return true;
- }
-
- switch (ch)
- {
- case '-':
- case '_':
- case '.':
- case '!':
- case '*':
- case '\'':
- case '(':
- case ')':
- return true;
- }
-
- return false;
- }
+ private static string? UrlEncode(string? str) =>
+ str is null ? null :
+ WebUtility.UrlEncode(str);
private void InvokeOperationCompleted(AsyncOperation asyncOp, SendOrPostCallback callback, AsyncCompletedEventArgs eventArgs)
{