diff --git a/src/libraries/Common/src/System/Net/WebHeaderEncoding.cs b/src/libraries/Common/src/System/Net/WebHeaderEncoding.cs deleted file mode 100644 index b654e07eb84376..00000000000000 --- a/src/libraries/Common/src/System/Net/WebHeaderEncoding.cs +++ /dev/null @@ -1,85 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; -using System.Text; - -namespace System.Net -{ - // we use this static class as a helper class to encode/decode HTTP headers. - // what we need is a 1-1 correspondence between a char in the range U+0000-U+00FF - // and a byte in the range 0x00-0xFF (which is the range that can hit the network). - // The Latin-1 encoding (ISO-88591-1) (GetEncoding(28591)) works for byte[] to string, but is a little slow. - // It doesn't work for string -> byte[] because of best-fit-mapping problems. - internal static class WebHeaderEncoding - { - internal static unsafe string GetString(byte[] bytes, int byteIndex, int byteCount) - { - if (byteCount < 1) - { - return string.Empty; - } - - Debug.Assert(bytes != null && (uint)byteIndex <= (uint)bytes.Length && (uint)(byteIndex + byteCount) <= (uint)bytes.Length); - - return string.Create(byteCount, (bytes, byteIndex), (buffer, state) => - { - fixed (byte* pByt = &state.bytes[state.byteIndex]) - fixed (char* pStr = buffer) - { - byte* pBytes = pByt; - char* pString = pStr; - int byteCount = buffer.Length; - - while (byteCount >= 8) - { - pString[0] = (char)pBytes[0]; - pString[1] = (char)pBytes[1]; - pString[2] = (char)pBytes[2]; - pString[3] = (char)pBytes[3]; - pString[4] = (char)pBytes[4]; - pString[5] = (char)pBytes[5]; - pString[6] = (char)pBytes[6]; - pString[7] = (char)pBytes[7]; - pString += 8; - pBytes += 8; - byteCount -= 8; - } - for (int i = 0; i < byteCount; i++) - { - pString[i] = (char)pBytes[i]; - } - } - }); - } - - internal static int GetByteCount(string myString) => myString.Length; - - internal static unsafe void GetBytes(string myString, int charIndex, int charCount, byte[] bytes, int byteIndex) - { - if (myString.Length == 0) - { - return; - } - - fixed (byte* bufferPointer = bytes) - { - byte* newBufferPointer = bufferPointer + byteIndex; - int finalIndex = charIndex + charCount; - while (charIndex < finalIndex) - { - *newBufferPointer++ = (byte)myString[charIndex++]; - } - } - } - internal static byte[] GetBytes(string myString) - { - byte[] bytes = new byte[myString.Length]; - if (myString.Length != 0) - { - GetBytes(myString, 0, myString.Length, bytes, 0); - } - return bytes; - } - } -} diff --git a/src/libraries/System.Net.HttpListener/src/System.Net.HttpListener.csproj b/src/libraries/System.Net.HttpListener/src/System.Net.HttpListener.csproj index 5f7c136659e1bf..81f3cb985a96d5 100644 --- a/src/libraries/System.Net.HttpListener/src/System.Net.HttpListener.csproj +++ b/src/libraries/System.Net.HttpListener/src/System.Net.HttpListener.csproj @@ -58,8 +58,6 @@ Link="Common\System\Net\LazyAsyncResult.cs" /> - diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerResponse.Managed.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerResponse.Managed.cs index 506a980ef526d1..a9b52f7002650e 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerResponse.Managed.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerResponse.Managed.cs @@ -270,7 +270,7 @@ internal void SendHeaders(bool closing, MemoryStream ms, bool isWebSocketHandsha StreamWriter writer = new StreamWriter(ms, encoding, 256); writer.Write("HTTP/1.1 {0} ", _statusCode); // "1.1" matches Windows implementation, which ignores the response version writer.Flush(); - byte[] statusDescriptionBytes = WebHeaderEncoding.GetBytes(StatusDescription); + byte[] statusDescriptionBytes = Encoding.Latin1.GetBytes(StatusDescription); ms.Write(statusDescriptionBytes, 0, statusDescriptionBytes.Length); writer.Write("\r\n"); diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListener.Windows.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListener.Windows.cs index fca60206bedfe9..b926a3dba1933b 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListener.Windows.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListener.Windows.cs @@ -1011,7 +1011,7 @@ public HttpListenerContext EndGetContext(IAsyncResult asyncResult) { bytes = Convert.FromBase64String(inBlob); - inBlob = WebHeaderEncoding.GetString(bytes, 0, bytes.Length); + inBlob = Encoding.Latin1.GetString(bytes); index = inBlob.IndexOf(':'); if (index != -1) diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerResponse.Windows.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerResponse.Windows.cs index 0f2779d4d4cc5e..6893ff918fe7d6 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerResponse.Windows.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerResponse.Windows.cs @@ -267,11 +267,10 @@ internal unsafe uint SendHeaders(Interop.HttpApi.HTTP_DATA_CHUNK* pDataChunk, if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, "Calling Interop.HttpApi.HttpSendHttpResponse flags:" + flags); if (StatusDescription.Length > 0) { - byte[] statusDescriptionBytes = new byte[WebHeaderEncoding.GetByteCount(StatusDescription)]; + byte[] statusDescriptionBytes = Encoding.Latin1.GetBytes(StatusDescription); fixed (byte* pStatusDescription = &statusDescriptionBytes[0]) { _nativeResponse.ReasonLength = (ushort)statusDescriptionBytes.Length; - WebHeaderEncoding.GetBytes(StatusDescription, 0, statusDescriptionBytes.Length, statusDescriptionBytes, 0); _nativeResponse.pReason = (sbyte*)pStatusDescription; fixed (Interop.HttpApi.HTTP_RESPONSE* pResponse = &_nativeResponse) { @@ -525,18 +524,16 @@ internal void ComputeCoreHeaders() for (int headerValueIndex = 0; headerValueIndex < headerValues.Length; headerValueIndex++) { //Add Name - bytes = new byte[WebHeaderEncoding.GetByteCount(headerName)]; + bytes = Encoding.Latin1.GetBytes(headerName); unknownHeaders[headers.UnknownHeaderCount].NameLength = (ushort)bytes.Length; - WebHeaderEncoding.GetBytes(headerName, 0, bytes.Length, bytes, 0); gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned); pinnedHeaders.Add(gcHandle); unknownHeaders[headers.UnknownHeaderCount].pName = (sbyte*)gcHandle.AddrOfPinnedObject(); //Add Value headerValue = headerValues[headerValueIndex]; - bytes = new byte[WebHeaderEncoding.GetByteCount(headerValue)]; + bytes = Encoding.Latin1.GetBytes(headerValue); unknownHeaders[headers.UnknownHeaderCount].RawValueLength = (ushort)bytes.Length; - WebHeaderEncoding.GetBytes(headerValue, 0, bytes.Length, bytes, 0); gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned); pinnedHeaders.Add(gcHandle); unknownHeaders[headers.UnknownHeaderCount].pRawValue = (sbyte*)gcHandle.AddrOfPinnedObject(); @@ -549,9 +546,8 @@ internal void ComputeCoreHeaders() if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"HttpResponseHeader[{lookup}]:{((HttpResponseHeader)lookup)} headerValue:{headerValue}"); if (headerValue != null) { - bytes = new byte[WebHeaderEncoding.GetByteCount(headerValue)]; + bytes = Encoding.Latin1.GetBytes(headerValue); pKnownHeaders[lookup].RawValueLength = (ushort)bytes.Length; - WebHeaderEncoding.GetBytes(headerValue, 0, bytes.Length, bytes, 0); gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned); pinnedHeaders.Add(gcHandle); pKnownHeaders[lookup].pRawValue = (sbyte*)gcHandle.AddrOfPinnedObject(); diff --git a/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.Headers.cs b/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.Headers.cs index 356add431e6140..c9e435d73bf257 100644 --- a/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.Headers.cs +++ b/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.Headers.cs @@ -401,7 +401,7 @@ public async Task StatusDescription_GetWithCustomStatusCode_ReturnsExpected(int [Theory] [InlineData("", "", 118)] - [InlineData("A !#\t1\u1234", "A !#\t14", 125)] // + [InlineData("A !#\t1\u1234", "A !#\t1?", 125)] // [InlineData("StatusDescription", "StatusDescription", 135)] [InlineData(" StatusDescription ", " StatusDescription ", 139)] public async Task StatusDescription_SetCustom_Success(string statusDescription, string expectedStatusDescription, int expectedNumberOfBytes)