public async Task SendAsync_SendZeroLengthPayloadAsEndOfMessage_Success(Uri server) { using (ClientWebSocket cws = await WebSocketHelper.GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) { var cts = new CancellationTokenSource(TimeOutMilliseconds); string message = "hello"; await cws.SendAsync( WebSocketData.GetBufferFromText(message), WebSocketMessageType.Text, false, cts.Token); Assert.Equal(WebSocketState.Open, cws.State); await cws.SendAsync(new ArraySegment <byte>(new byte[0]), WebSocketMessageType.Text, true, cts.Token); Assert.Equal(WebSocketState.Open, cws.State); var recvBuffer = new byte[100]; var receiveSegment = new ArraySegment <byte>(recvBuffer); WebSocketReceiveResult recvRet = await cws.ReceiveAsync(receiveSegment, cts.Token); Assert.Equal(WebSocketState.Open, cws.State); Assert.Equal(message.Length, recvRet.Count); Assert.Equal(WebSocketMessageType.Text, recvRet.MessageType); Assert.Equal(true, recvRet.EndOfMessage); Assert.Equal(null, recvRet.CloseStatus); Assert.Equal(null, recvRet.CloseStatusDescription); var recvSegment = new ArraySegment <byte>(receiveSegment.Array, receiveSegment.Offset, recvRet.Count); Assert.Equal(message, WebSocketData.GetTextFromBuffer(recvSegment)); } }
public async Task ConnectAsync_AddCustomHeaders_Success(Uri server) { using (var cws = new ClientWebSocket()) { cws.Options.SetRequestHeader("X-CustomHeader1", "Value1"); cws.Options.SetRequestHeader("X-CustomHeader2", "Value2"); using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) { Task taskConnect = cws.ConnectAsync(server, cts.Token); Assert.True( (cws.State == WebSocketState.None) || (cws.State == WebSocketState.Connecting) || (cws.State == WebSocketState.Open), "State immediately after ConnectAsync incorrect: " + cws.State); await taskConnect; } Assert.Equal(WebSocketState.Open, cws.State); byte[] buffer = new byte[65536]; var segment = new ArraySegment <byte>(buffer, 0, buffer.Length); WebSocketReceiveResult recvResult; using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) { recvResult = await cws.ReceiveAsync(segment, cts.Token); } Assert.Equal(WebSocketMessageType.Text, recvResult.MessageType); string headers = WebSocketData.GetTextFromBuffer(segment); Assert.True(headers.Contains("X-CustomHeader1:Value1")); Assert.True(headers.Contains("X-CustomHeader2:Value2")); await cws.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None); } }
public static async Task TestEcho( Uri server, WebSocketMessageType type, int timeOutMilliseconds, ITestOutputHelper output, HttpMessageInvoker?invoker = null) { var cts = new CancellationTokenSource(timeOutMilliseconds); string message = "Hello WebSockets!"; string closeMessage = "Good bye!"; var receiveBuffer = new byte[100]; var receiveSegment = new ArraySegment <byte>(receiveBuffer); using (ClientWebSocket cws = await GetConnectedWebSocket(server, timeOutMilliseconds, output, invoker: invoker)) { output.WriteLine("TestEcho: SendAsync starting."); await cws.SendAsync(WebSocketData.GetBufferFromText(message), type, true, cts.Token); output.WriteLine("TestEcho: SendAsync done."); Assert.Equal(WebSocketState.Open, cws.State); output.WriteLine("TestEcho: ReceiveAsync starting."); WebSocketReceiveResult recvRet = await cws.ReceiveAsync(receiveSegment, cts.Token); output.WriteLine("TestEcho: ReceiveAsync done."); Assert.Equal(WebSocketState.Open, cws.State); Assert.Equal(message.Length, recvRet.Count); Assert.Equal(type, recvRet.MessageType); Assert.True(recvRet.EndOfMessage); Assert.Null(recvRet.CloseStatus); Assert.Null(recvRet.CloseStatusDescription); var recvSegment = new ArraySegment <byte>(receiveSegment.Array, receiveSegment.Offset, recvRet.Count); Assert.Equal(message, WebSocketData.GetTextFromBuffer(recvSegment)); output.WriteLine("TestEcho: CloseAsync starting."); Task taskClose = cws.CloseAsync(WebSocketCloseStatus.NormalClosure, closeMessage, cts.Token); Assert.True( (cws.State == WebSocketState.Open) || (cws.State == WebSocketState.CloseSent) || (cws.State == WebSocketState.CloseReceived) || (cws.State == WebSocketState.Closed), "State immediately after CloseAsync : " + cws.State); await taskClose; output.WriteLine("TestEcho: CloseAsync done."); Assert.Equal(WebSocketState.Closed, cws.State); Assert.Equal(WebSocketCloseStatus.NormalClosure, cws.CloseStatus); Assert.Equal(closeMessage, cws.CloseStatusDescription); } }
public async Task ConnectAsync_CookieHeaders_Success(Uri server) { using (var cws = new ClientWebSocket()) { Assert.Null(cws.Options.Cookies); cws.Options.Cookies = new CookieContainer(); Cookie cookie1 = new Cookie("Cookies", "Are Yummy"); Cookie cookie2 = new Cookie("Especially", "Chocolate Chip"); Cookie secureCookie = new Cookie("Occasionally", "Raisin"); secureCookie.Secure = true; cws.Options.Cookies.Add(server, cookie1); cws.Options.Cookies.Add(server, cookie2); cws.Options.Cookies.Add(server, secureCookie); using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) { Task taskConnect = cws.ConnectAsync(server, cts.Token); Assert.True( cws.State == WebSocketState.None || cws.State == WebSocketState.Connecting || cws.State == WebSocketState.Open, "State immediately after ConnectAsync incorrect: " + cws.State); await taskConnect; } Assert.Equal(WebSocketState.Open, cws.State); byte[] buffer = new byte[65536]; var segment = new ArraySegment <byte>(buffer); WebSocketReceiveResult recvResult; using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) { recvResult = await cws.ReceiveAsync(segment, cts.Token); } Assert.Equal(WebSocketMessageType.Text, recvResult.MessageType); string headers = WebSocketData.GetTextFromBuffer(segment); Assert.True(headers.Contains("Cookies=Are Yummy")); Assert.True(headers.Contains("Especially=Chocolate Chip")); Assert.Equal(server.Scheme == "wss", headers.Contains("Occasionally=Raisin")); await cws.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None); } }
public async Task ConnectAsync_AddHostHeader_Success() { Uri server = System.Net.Test.Common.Configuration.WebSockets.RemoteEchoServer; // Send via the physical address such as "corefx-net.cloudapp.net" // Set the Host header to logical address like "subdomain.corefx-net.cloudapp.net" // Verify the scenario works and the remote server received "Host: subdomain.corefx-net.cloudapp.net" string logicalHost = "subdomain." + server.Host; using (var cws = new ClientWebSocket()) { // Set the Host header to the logical address cws.Options.SetRequestHeader("Host", logicalHost); using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) { // Connect using the physical address Task taskConnect = cws.ConnectAsync(server, cts.Token); Assert.True( (cws.State == WebSocketState.None) || (cws.State == WebSocketState.Connecting) || (cws.State == WebSocketState.Open), "State immediately after ConnectAsync incorrect: " + cws.State); await taskConnect; } Assert.Equal(WebSocketState.Open, cws.State); byte[] buffer = new byte[65536]; var segment = new ArraySegment <byte>(buffer, 0, buffer.Length); WebSocketReceiveResult recvResult; using (var cts = new CancellationTokenSource(TimeOutMilliseconds)) { recvResult = await cws.ReceiveAsync(segment, cts.Token); } Assert.Equal(WebSocketMessageType.Text, recvResult.MessageType); string headers = WebSocketData.GetTextFromBuffer(segment); Assert.Contains($"Host:{logicalHost}", headers, StringComparison.Ordinal); await cws.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None); } }
public async Task CloseOutputAsync_ClientInitiated_CanReceive_CanClose(Uri server) { string message = "Hello WebSockets!"; using (ClientWebSocket cws = await WebSocketHelper.GetConnectedWebSocket(server, TimeOutMilliseconds, _output)) { var cts = new CancellationTokenSource(TimeOutMilliseconds); // See issue for Browser websocket differences https://github.com/dotnet/runtime/issues/45538 var closeStatus = PlatformDetection.IsBrowser ? WebSocketCloseStatus.NormalClosure : WebSocketCloseStatus.InvalidPayloadData; string closeDescription = "CloseOutputAsync_Client_InvalidPayloadData"; await cws.SendAsync(WebSocketData.GetBufferFromText(message), WebSocketMessageType.Text, true, cts.Token); // Need a short delay as per WebSocket rfc6455 section 5.5.1 there isn't a requirement to receive any // data fragments after a close has been sent. The delay allows the received data fragment to be // available before calling close. The WinRT MessageWebSocket implementation doesn't allow receiving // after a call to Close. await Task.Delay(500); await cws.CloseOutputAsync(closeStatus, closeDescription, cts.Token); // Should be able to receive the message echoed by the server. var recvBuffer = new byte[100]; var segmentRecv = new ArraySegment <byte>(recvBuffer); WebSocketReceiveResult recvResult = await cws.ReceiveAsync(segmentRecv, cts.Token); Assert.Equal(message.Length, recvResult.Count); segmentRecv = new ArraySegment <byte>(segmentRecv.Array, 0, recvResult.Count); Assert.Equal(message, WebSocketData.GetTextFromBuffer(segmentRecv)); Assert.Null(recvResult.CloseStatus); Assert.Null(recvResult.CloseStatusDescription); await cws.CloseAsync(closeStatus, closeDescription, cts.Token); Assert.Equal(closeStatus, cws.CloseStatus); Assert.Equal(closeDescription, cws.CloseStatusDescription); } }