From 5081756d99d3971a9987d39c49d69bd4af3c1027 Mon Sep 17 00:00:00 2001 From: Marc Brooks Date: Thu, 23 Mar 2023 11:42:24 -0500 Subject: [PATCH 1/9] Allow non RFC close statuses in ManagedWebSocket Add ServiceRestart (1012), TryAgainLater (1013), and BadGateway (1014) to the list of `WebSocketCloseStatus` values and allow them to be used as valid WebSocket close statuses so we don't reject the close and discard the status description by adding them to the private `IsValueCloseStatus` method switch statement declaring them as valid `true`. These codes are documented [here as IANA registered codes](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code) as valid server-initiated close reasons. Fixes Issue https://github.com/dotnet/runtime/issues/82602 --- .../System/Net/WebSockets/ManagedWebSocket.cs | 3 + .../Net/WebSockets/WebSocketCloseStatus.cs | 4 + .../tests/System.Net.WebSockets.Tests.csproj | 1 + .../tests/WebSocketCloseTests.cs | 94 +++++++++++++++++++ 4 files changed, 102 insertions(+) create mode 100644 src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs diff --git a/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/ManagedWebSocket.cs b/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/ManagedWebSocket.cs index 48a55b462c1c04..114cbbe92d5bf0 100644 --- a/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/ManagedWebSocket.cs +++ b/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/ManagedWebSocket.cs @@ -1059,6 +1059,9 @@ private static bool IsValidCloseStatus(WebSocketCloseStatus closeStatus) case WebSocketCloseStatus.NormalClosure: case WebSocketCloseStatus.PolicyViolation: case WebSocketCloseStatus.ProtocolError: + case (WebSocketCloseStatus)1012: // ServiceRestart + case (WebSocketCloseStatus)1013: // TryAgainLater + case (WebSocketCloseStatus)1014: // BadGateway return true; default: diff --git a/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/WebSocketCloseStatus.cs b/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/WebSocketCloseStatus.cs index 235dc86bbbeca4..4297289257b616 100644 --- a/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/WebSocketCloseStatus.cs +++ b/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/WebSocketCloseStatus.cs @@ -18,6 +18,10 @@ public enum WebSocketCloseStatus MessageTooBig = 1009, MandatoryExtension = 1010, InternalServerError = 1011 + //non-RFC IANA registered status codes that we allow as valid closing status + // ServiceRestart = 1012, // indicates that the server / service is restarting. + // TryAgainLater = 1013, // indicates that a temporary server condition forced blocking the client's request. + // BadGateway = 1014 // indicates that the server acting as gateway received an invalid response // TLSHandshakeFailed = 1015, // 1015 is reserved and should never be used by user // 0 - 999 Status codes in the range 0-999 are not used. diff --git a/src/libraries/System.Net.WebSockets/tests/System.Net.WebSockets.Tests.csproj b/src/libraries/System.Net.WebSockets/tests/System.Net.WebSockets.Tests.csproj index 8af7c5bed35079..f49bdcbbac0dee 100644 --- a/src/libraries/System.Net.WebSockets/tests/System.Net.WebSockets.Tests.csproj +++ b/src/libraries/System.Net.WebSockets/tests/System.Net.WebSockets.Tests.csproj @@ -6,6 +6,7 @@ + diff --git a/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs b/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs new file mode 100644 index 00000000000000..8af6a545c2942e --- /dev/null +++ b/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs @@ -0,0 +1,94 @@ +// 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; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace System.Net.WebSockets.Tests +{ + public class WebSocketCloseTests + { + private readonly CancellationTokenSource? _cancellation; + + public WebSocketCloseTests() + { + if (!Debugger.IsAttached) + { + _cancellation = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + } + } + + public CancellationToken CancellationToken => _cancellation?.Token ?? default; + + public static object[][] ClosesData = { + new object[] { WebSocketCloseStatus.EndpointUnavailable }, + new object[] { WebSocketCloseStatus.InternalServerError }, + new object[] { WebSocketCloseStatus.InvalidMessageType}, + new object[] { WebSocketCloseStatus.InvalidPayloadData }, + new object[] { WebSocketCloseStatus.MandatoryExtension }, + new object[] { WebSocketCloseStatus.MessageTooBig }, + new object[] { WebSocketCloseStatus.NormalClosure }, + new object[] { WebSocketCloseStatus.PolicyViolation }, + new object[] { WebSocketCloseStatus.ProtocolError }, + new object[] { (WebSocketCloseStatus)1012 }, // ServiceRestart indicates that the server / service is restarting. + new object[] { (WebSocketCloseStatus)1013 }, // TryAgainLater indicates that a temporary server condition forced blocking the client's request. + new object[] { (WebSocketCloseStatus)1014 }, // BadGateway indicates that the server acting as gateway received an invalid response + }; + + [Theory] + [MemberData(nameof(ClosesData))] + public void WebSocketReceiveResult_WebSocketCloseStatus_Roundtrip(WebSocketCloseStatus closeStatus) + { + string closeStatusDescription = "closeStatus " + closeStatus.ToString(); + WebSocketReceiveResult wsrr = new WebSocketReceiveResult(42, WebSocketMessageType.Close, true, closeStatus, closeStatusDescription); + Assert.Equal(42, wsrr.Count); + Assert.Equal(closeStatus, wsrr.CloseStatus); + Assert.Equal(closeStatusDescription, wsrr.CloseStatusDescription); + } + + [Theory] + [MemberData(nameof(ClosesData))] + public async Task ReceivesClose(WebSocketCloseStatus closeStatus) + { + WebSocketTestStream stream = new(); + using (WebSocket server = WebSocket.CreateFromStream(stream, true, null, TimeSpan.FromSeconds(3))) + using (WebSocket client = WebSocket.CreateFromStream(stream.Remote, false, null, TimeSpan.FromSeconds(3))) + { + Assert.NotNull(server); + Assert.NotNull(client); + + string closeStatusDescription = "closeStatus " + closeStatus.ToString(); + await SendTextAsync(closeStatusDescription, server); + var response = await ReceiveAsync(client); + Assert.Equal(closeStatusDescription, response); + + string closed = "Closed"; + await SendTextAsync(closed, server); + await server.CloseOutputAsync(closeStatus, closeStatusDescription, CancellationToken); + + var received = await ReceiveAsync(client); + Assert.Equal(closed, received); + } + } + + private async Task ReceiveAsync(WebSocket client) + { + var buffer = new byte[1024]; + ValueWebSocketReceiveResult result = await client.ReceiveAsync(buffer.AsMemory(), CancellationToken); + + Assert.True(result.EndOfMessage); + Assert.Equal(WebSocketMessageType.Text, result.MessageType); + return Encoding.UTF8.GetString(buffer.AsSpan(0, result.Count)); + } + + private ValueTask SendTextAsync(string text, WebSocket websocket) + { + WebSocketMessageFlags flags = WebSocketMessageFlags.EndOfMessage | WebSocketMessageFlags.DisableCompression; + byte[] bytes = Encoding.UTF8.GetBytes(text); + return websocket.SendAsync(bytes.AsMemory(), WebSocketMessageType.Text, flags, CancellationToken); + } + } +} From e06f8100fe17bd6e7fb0282be4581e280f8b8766 Mon Sep 17 00:00:00 2001 From: Marc Brooks Date: Thu, 23 Mar 2023 12:26:07 -0500 Subject: [PATCH 2/9] Cleanup comment format Co-authored-by: MartyIX <203266+MartyIX@users.noreply.github.com> --- .../src/System/Net/WebSockets/WebSocketCloseStatus.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/WebSocketCloseStatus.cs b/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/WebSocketCloseStatus.cs index 4297289257b616..0608a831f85f92 100644 --- a/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/WebSocketCloseStatus.cs +++ b/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/WebSocketCloseStatus.cs @@ -18,7 +18,7 @@ public enum WebSocketCloseStatus MessageTooBig = 1009, MandatoryExtension = 1010, InternalServerError = 1011 - //non-RFC IANA registered status codes that we allow as valid closing status + // non-RFC IANA registered status codes that we allow as valid closing status // ServiceRestart = 1012, // indicates that the server / service is restarting. // TryAgainLater = 1013, // indicates that a temporary server condition forced blocking the client's request. // BadGateway = 1014 // indicates that the server acting as gateway received an invalid response From 76f873ad5218cadf3598e880f4770e55d1121e99 Mon Sep 17 00:00:00 2001 From: Marc Brooks Date: Mon, 27 Mar 2023 15:18:05 -0500 Subject: [PATCH 3/9] Rename test data to CloseStatuses Co-authored-by: Natalia Kondratyeva --- .../System.Net.WebSockets/tests/WebSocketCloseTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs b/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs index 8af6a545c2942e..dfed125a6d27fb 100644 --- a/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs +++ b/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs @@ -23,7 +23,7 @@ public WebSocketCloseTests() public CancellationToken CancellationToken => _cancellation?.Token ?? default; - public static object[][] ClosesData = { + public static object[][] CloseStatuses = { new object[] { WebSocketCloseStatus.EndpointUnavailable }, new object[] { WebSocketCloseStatus.InternalServerError }, new object[] { WebSocketCloseStatus.InvalidMessageType}, From 4ae46f08b08c41f68151a006fc6014f3a386117f Mon Sep 17 00:00:00 2001 From: Marc Brooks Date: Mon, 27 Mar 2023 15:18:15 -0500 Subject: [PATCH 4/9] Rename test method to follow naming convention. Co-authored-by: Natalia Kondratyeva --- .../System.Net.WebSockets/tests/WebSocketCloseTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs b/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs index dfed125a6d27fb..f601f75344cf34 100644 --- a/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs +++ b/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs @@ -51,7 +51,7 @@ public void WebSocketReceiveResult_WebSocketCloseStatus_Roundtrip(WebSocketClose [Theory] [MemberData(nameof(ClosesData))] - public async Task ReceivesClose(WebSocketCloseStatus closeStatus) + public async Task ReceiveAsync_ValidCloseStatus_Success(WebSocketCloseStatus closeStatus) { WebSocketTestStream stream = new(); using (WebSocket server = WebSocket.CreateFromStream(stream, true, null, TimeSpan.FromSeconds(3))) From 8a2cc0a2ad969535619bb7d547cbab60b7368188 Mon Sep 17 00:00:00 2001 From: Marc Brooks Date: Mon, 27 Mar 2023 16:33:40 -0500 Subject: [PATCH 5/9] Addressed PR feedback Finished rename of CloseStatuses test data Renamed `closeStatusDescription` to `serverMessage` Send hello message and close status then await both responses and check they are as expected. This necessitated switching to the `ReceiveAsync` that accepts an `ArraySegment`. Explicitly typed `var`s Inlined helper methods (for clarity) --- .../tests/WebSocketCloseTests.cs | 57 +++++++++---------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs b/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs index f601f75344cf34..b9e89b9989a045 100644 --- a/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs +++ b/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs @@ -39,56 +39,51 @@ public WebSocketCloseTests() }; [Theory] - [MemberData(nameof(ClosesData))] + [MemberData(nameof(CloseStatuses))] public void WebSocketReceiveResult_WebSocketCloseStatus_Roundtrip(WebSocketCloseStatus closeStatus) { - string closeStatusDescription = "closeStatus " + closeStatus.ToString(); - WebSocketReceiveResult wsrr = new WebSocketReceiveResult(42, WebSocketMessageType.Close, true, closeStatus, closeStatusDescription); + string serverMessage = "closeStatus " + closeStatus.ToString(); + WebSocketReceiveResult wsrr = new WebSocketReceiveResult(42, WebSocketMessageType.Close, true, closeStatus, serverMessage); Assert.Equal(42, wsrr.Count); Assert.Equal(closeStatus, wsrr.CloseStatus); - Assert.Equal(closeStatusDescription, wsrr.CloseStatusDescription); + Assert.Equal(serverMessage, wsrr.CloseStatusDescription); } [Theory] - [MemberData(nameof(ClosesData))] + [MemberData(nameof(CloseStatuses))] public async Task ReceiveAsync_ValidCloseStatus_Success(WebSocketCloseStatus closeStatus) { + byte[] receiveBuffer = new byte[1024]; WebSocketTestStream stream = new(); + Encoding encoding = Encoding.UTF8; + using (WebSocket server = WebSocket.CreateFromStream(stream, true, null, TimeSpan.FromSeconds(3))) using (WebSocket client = WebSocket.CreateFromStream(stream.Remote, false, null, TimeSpan.FromSeconds(3))) { Assert.NotNull(server); Assert.NotNull(client); - string closeStatusDescription = "closeStatus " + closeStatus.ToString(); - await SendTextAsync(closeStatusDescription, server); - var response = await ReceiveAsync(client); - Assert.Equal(closeStatusDescription, response); + // send something + string hello = "Testing " + closeStatus.ToString(); + byte[] sendBytes = encoding.GetBytes(hello); + await server.SendAsync(sendBytes.AsMemory(), WebSocketMessageType.Text, WebSocketMessageFlags.DisableCompression, CancellationToken); - string closed = "Closed"; - await SendTextAsync(closed, server); - await server.CloseOutputAsync(closeStatus, closeStatusDescription, CancellationToken); + // and then server-side close with the test status + string serverMessage = "CloseStatus " + closeStatus.ToString(); + await server.CloseOutputAsync(closeStatus, serverMessage, CancellationToken); - var received = await ReceiveAsync(client); - Assert.Equal(closed, received); - } - } - - private async Task ReceiveAsync(WebSocket client) - { - var buffer = new byte[1024]; - ValueWebSocketReceiveResult result = await client.ReceiveAsync(buffer.AsMemory(), CancellationToken); + // get the hello from the client (after the close message was sent) + WebSocketReceiveResult result = await client.ReceiveAsync(new ArraySegment(receiveBuffer), CancellationToken); + Assert.Equal(WebSocketMessageType.Text, result.MessageType); + string response = encoding.GetString(receiveBuffer.AsSpan(0, result.Count)); + Assert.Equal(hello, response); - Assert.True(result.EndOfMessage); - Assert.Equal(WebSocketMessageType.Text, result.MessageType); - return Encoding.UTF8.GetString(buffer.AsSpan(0, result.Count)); - } - - private ValueTask SendTextAsync(string text, WebSocket websocket) - { - WebSocketMessageFlags flags = WebSocketMessageFlags.EndOfMessage | WebSocketMessageFlags.DisableCompression; - byte[] bytes = Encoding.UTF8.GetBytes(text); - return websocket.SendAsync(bytes.AsMemory(), WebSocketMessageType.Text, flags, CancellationToken); + // now look for the expected close status + WebSocketReceiveResult closing = await client.ReceiveAsync(new ArraySegment(receiveBuffer), CancellationToken); + Assert.Equal(WebSocketMessageType.Close, closing.MessageType); + Assert.Equal(closeStatus, closing.CloseStatus); + Assert.Equal(serverMessage, closing.CloseStatusDescription); + } } } } From e479a56a9d0bbf1200610926abedd61d7e4a153f Mon Sep 17 00:00:00 2001 From: Marc Brooks Date: Thu, 30 Mar 2023 14:29:41 -0500 Subject: [PATCH 6/9] Rename local for per PR feedback Swapping back to a distinct and more appropriately named variable for the `closeStatusDescription` Co-authored-by: Natalia Kondratyeva --- .../System.Net.WebSockets/tests/WebSocketCloseTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs b/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs index b9e89b9989a045..0612c11580c0e5 100644 --- a/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs +++ b/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs @@ -42,11 +42,11 @@ public WebSocketCloseTests() [MemberData(nameof(CloseStatuses))] public void WebSocketReceiveResult_WebSocketCloseStatus_Roundtrip(WebSocketCloseStatus closeStatus) { - string serverMessage = "closeStatus " + closeStatus.ToString(); - WebSocketReceiveResult wsrr = new WebSocketReceiveResult(42, WebSocketMessageType.Close, true, closeStatus, serverMessage); + string closeStatusDescription = "closeStatus " + closeStatus.ToString(); + WebSocketReceiveResult wsrr = new WebSocketReceiveResult(42, WebSocketMessageType.Close, true, closeStatus, closeStatusDescription); Assert.Equal(42, wsrr.Count); Assert.Equal(closeStatus, wsrr.CloseStatus); - Assert.Equal(serverMessage, wsrr.CloseStatusDescription); + Assert.Equal(closeStatusDescription, wsrr.CloseStatusDescription); } [Theory] From 9e15dec1446b4061dc8d27ef0c01c71e97c64b0d Mon Sep 17 00:00:00 2001 From: Marc Brooks Date: Thu, 30 Mar 2023 14:30:25 -0500 Subject: [PATCH 7/9] Label the boolean for isServer flag Co-authored-by: Natalia Kondratyeva --- .../System.Net.WebSockets/tests/WebSocketCloseTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs b/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs index 0612c11580c0e5..ee2223a4f42df3 100644 --- a/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs +++ b/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs @@ -57,8 +57,8 @@ public async Task ReceiveAsync_ValidCloseStatus_Success(WebSocketCloseStatus clo WebSocketTestStream stream = new(); Encoding encoding = Encoding.UTF8; - using (WebSocket server = WebSocket.CreateFromStream(stream, true, null, TimeSpan.FromSeconds(3))) - using (WebSocket client = WebSocket.CreateFromStream(stream.Remote, false, null, TimeSpan.FromSeconds(3))) + using (WebSocket server = WebSocket.CreateFromStream(stream, isServer: true, null, TimeSpan.FromSeconds(3))) + using (WebSocket client = WebSocket.CreateFromStream(stream.Remote, isServer: false, null, TimeSpan.FromSeconds(3))) { Assert.NotNull(server); Assert.NotNull(client); From e349b33f8ccf985da2b44d01d697157b0ba76ce0 Mon Sep 17 00:00:00 2001 From: Marc Brooks Date: Thu, 30 Mar 2023 14:38:13 -0500 Subject: [PATCH 8/9] Use better local variable name Renamed local `serverMessage` back to `closeStatusDescription` per PR feedback. Co-authored-by: Natalia Kondratyeva --- .../System.Net.WebSockets/tests/WebSocketCloseTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs b/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs index ee2223a4f42df3..05e03beb991190 100644 --- a/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs +++ b/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs @@ -69,8 +69,8 @@ public async Task ReceiveAsync_ValidCloseStatus_Success(WebSocketCloseStatus clo await server.SendAsync(sendBytes.AsMemory(), WebSocketMessageType.Text, WebSocketMessageFlags.DisableCompression, CancellationToken); // and then server-side close with the test status - string serverMessage = "CloseStatus " + closeStatus.ToString(); - await server.CloseOutputAsync(closeStatus, serverMessage, CancellationToken); + string closeStatusDescription = "CloseStatus " + closeStatus.ToString(); + await server.CloseOutputAsync(closeStatus, closeStatusDescription, CancellationToken); // get the hello from the client (after the close message was sent) WebSocketReceiveResult result = await client.ReceiveAsync(new ArraySegment(receiveBuffer), CancellationToken); From 1633968a5880e88fd3219bf667ef19a2f0f47edf Mon Sep 17 00:00:00 2001 From: Marc Brooks Date: Thu, 30 Mar 2023 15:19:51 -0500 Subject: [PATCH 9/9] Address PR and rebase to main Rebased to current main, updated the commit messages and added the remaining changes to address the PR comments. --- .../System.Net.WebSockets/tests/WebSocketCloseTests.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs b/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs index 05e03beb991190..86d1dfb2cd530a 100644 --- a/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs +++ b/src/libraries/System.Net.WebSockets/tests/WebSocketCloseTests.cs @@ -43,7 +43,7 @@ public WebSocketCloseTests() public void WebSocketReceiveResult_WebSocketCloseStatus_Roundtrip(WebSocketCloseStatus closeStatus) { string closeStatusDescription = "closeStatus " + closeStatus.ToString(); - WebSocketReceiveResult wsrr = new WebSocketReceiveResult(42, WebSocketMessageType.Close, true, closeStatus, closeStatusDescription); + WebSocketReceiveResult wsrr = new WebSocketReceiveResult(42, WebSocketMessageType.Close, endOfMessage: true, closeStatus, closeStatusDescription); Assert.Equal(42, wsrr.Count); Assert.Equal(closeStatus, wsrr.CloseStatus); Assert.Equal(closeStatusDescription, wsrr.CloseStatusDescription); @@ -57,8 +57,8 @@ public async Task ReceiveAsync_ValidCloseStatus_Success(WebSocketCloseStatus clo WebSocketTestStream stream = new(); Encoding encoding = Encoding.UTF8; - using (WebSocket server = WebSocket.CreateFromStream(stream, isServer: true, null, TimeSpan.FromSeconds(3))) - using (WebSocket client = WebSocket.CreateFromStream(stream.Remote, isServer: false, null, TimeSpan.FromSeconds(3))) + using (WebSocket server = WebSocket.CreateFromStream(stream, isServer: true, subProtocol: null, TimeSpan.FromSeconds(3))) + using (WebSocket client = WebSocket.CreateFromStream(stream.Remote, isServer: false, subProtocol: null, TimeSpan.FromSeconds(3))) { Assert.NotNull(server); Assert.NotNull(client); @@ -66,7 +66,7 @@ public async Task ReceiveAsync_ValidCloseStatus_Success(WebSocketCloseStatus clo // send something string hello = "Testing " + closeStatus.ToString(); byte[] sendBytes = encoding.GetBytes(hello); - await server.SendAsync(sendBytes.AsMemory(), WebSocketMessageType.Text, WebSocketMessageFlags.DisableCompression, CancellationToken); + await server.SendAsync(sendBytes.AsMemory(), WebSocketMessageType.Text, WebSocketMessageFlags.None, CancellationToken); // and then server-side close with the test status string closeStatusDescription = "CloseStatus " + closeStatus.ToString(); @@ -82,7 +82,7 @@ public async Task ReceiveAsync_ValidCloseStatus_Success(WebSocketCloseStatus clo WebSocketReceiveResult closing = await client.ReceiveAsync(new ArraySegment(receiveBuffer), CancellationToken); Assert.Equal(WebSocketMessageType.Close, closing.MessageType); Assert.Equal(closeStatus, closing.CloseStatus); - Assert.Equal(serverMessage, closing.CloseStatusDescription); + Assert.Equal(closeStatusDescription, closing.CloseStatusDescription); } } }