Esempio n. 1
0
 public async Task SendAsync_Cancel_Success(Uri server)
 {
     await TestCancellation((cws) =>
     {
         var cts = new CancellationTokenSource(5);
         return(cws.SendAsync(
                    WebSocketData.GetBufferFromText(".delay5sec"),
                    WebSocketMessageType.Text,
                    true,
                    cts.Token));
     }, server);
 }
Esempio n. 2
0
        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);
            }
        }
Esempio n. 3
0
        public async Task Abort_SendAndAbort_Success(Uri server)
        {
            await TestCancellation(async (cws) => {
                var cts = new CancellationTokenSource(TimeOutMilliseconds);

                Task t = cws.SendAsync(
                    WebSocketData.GetBufferFromText(".delay5sec"),
                    WebSocketMessageType.Text,
                    true,
                    cts.Token);

                cws.Abort();

                await t;
            }, server);
        }
Esempio n. 4
0
        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);
            }
        }
Esempio n. 5
0
        public async Task CloseAsync_ServerInitiatedClose_Success(Uri server, bool useCloseOutputAsync)
        {
            const string closeWebSocketMetaCommand = ".close";

            using (ClientWebSocket cws = await GetConnectedWebSocket(server, TimeOutMilliseconds, _output))
            {
                var cts = new CancellationTokenSource(TimeOutMilliseconds);

                _output.WriteLine("SendAsync starting.");
                await cws.SendAsync(
                    WebSocketData.GetBufferFromText(closeWebSocketMetaCommand),
                    WebSocketMessageType.Text,
                    true,
                    cts.Token);

                _output.WriteLine("SendAsync done.");

                var recvBuffer = new byte[256];
                _output.WriteLine("ReceiveAsync starting.");
                WebSocketReceiveResult recvResult = await cws.ReceiveAsync(new ArraySegment <byte>(recvBuffer), cts.Token);

                _output.WriteLine("ReceiveAsync done.");

                // Verify received server-initiated close message.
                Assert.Equal(WebSocketCloseStatus.NormalClosure, recvResult.CloseStatus);
                Assert.Equal(closeWebSocketMetaCommand, recvResult.CloseStatusDescription);
                Assert.Equal(WebSocketMessageType.Close, recvResult.MessageType);

                // Verify current websocket state as CloseReceived which indicates only partial close.
                Assert.Equal(WebSocketState.CloseReceived, cws.State);
                Assert.Equal(WebSocketCloseStatus.NormalClosure, cws.CloseStatus);
                Assert.Equal(closeWebSocketMetaCommand, cws.CloseStatusDescription);

                // Send back close message to acknowledge server-initiated close.
                _output.WriteLine("Close starting.");
                await(useCloseOutputAsync ?
                      cws.CloseOutputAsync(WebSocketCloseStatus.InvalidMessageType, string.Empty, cts.Token) :
                      cws.CloseAsync(WebSocketCloseStatus.InvalidMessageType, string.Empty, cts.Token));
                _output.WriteLine("Close done.");
                Assert.Equal(WebSocketState.Closed, cws.State);

                // Verify that there is no follow-up echo close message back from the server by
                // making sure the close code and message are the same as from the first server close message.
                Assert.Equal(WebSocketCloseStatus.NormalClosure, cws.CloseStatus);
                Assert.Equal(closeWebSocketMetaCommand, cws.CloseStatusDescription);
            }
        }
Esempio n. 6
0
        public async Task CloseOutputAsync_ServerInitiated_CanSend(Uri server)
        {
            string message                  = "Hello WebSockets!";
            var    expectedCloseStatus      = WebSocketCloseStatus.NormalClosure;
            var    expectedCloseDescription = ".shutdown";

            using (ClientWebSocket cws = await WebSocketHelper.GetConnectedWebSocket(server, TimeOutMilliseconds, _output))
            {
                var cts = new CancellationTokenSource(TimeOutMilliseconds);

                await cws.SendAsync(
                    WebSocketData.GetBufferFromText(".shutdown"),
                    WebSocketMessageType.Text,
                    true,
                    cts.Token);

                // Should be able to receive a shutdown message.
                var recvBuffer  = new byte[100];
                var segmentRecv = new ArraySegment <byte>(recvBuffer);
                WebSocketReceiveResult recvResult = await cws.ReceiveAsync(segmentRecv, cts.Token);

                Assert.Equal(0, recvResult.Count);
                Assert.Equal(expectedCloseStatus, recvResult.CloseStatus);
                Assert.Equal(expectedCloseDescription, recvResult.CloseStatusDescription);

                // Verify WebSocket state
                Assert.Equal(expectedCloseStatus, cws.CloseStatus);
                Assert.Equal(expectedCloseDescription, cws.CloseStatusDescription);

                Assert.Equal(WebSocketState.CloseReceived, cws.State);

                // Should be able to send.
                await cws.SendAsync(WebSocketData.GetBufferFromText(message), WebSocketMessageType.Text, true, cts.Token);

                // Cannot change the close status/description with the final close.
                var closeStatus      = WebSocketCloseStatus.InvalidPayloadData;
                var closeDescription = "CloseOutputAsync_Client_Description";

                await cws.CloseAsync(closeStatus, closeDescription, cts.Token);

                Assert.Equal(expectedCloseStatus, cws.CloseStatus);
                Assert.Equal(expectedCloseDescription, cws.CloseStatusDescription);
                Assert.Equal(WebSocketState.Closed, cws.State);
            }
        }
Esempio n. 7
0
        public async Task CloseOutputAsync_Cancel_Success(Uri server)
        {
            await TestCancellation(async (cws) => {
                var cts        = new CancellationTokenSource(5);
                var ctsDefault = new CancellationTokenSource(TimeOutMilliseconds);

                await cws.SendAsync(
                    WebSocketData.GetBufferFromText(".delay5sec"),
                    WebSocketMessageType.Text,
                    true,
                    ctsDefault.Token);

                var recvBuffer = new byte[100];
                var segment    = new ArraySegment <byte>(recvBuffer);

                await cws.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "CancelShutdown", cts.Token);
            }, server);
        }
        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);
            }
        }
Esempio n. 9
0
        public async Task Abort_ReceiveAndAbort_Success(Uri server)
        {
            await TestCancellation(async (cws) => {
                var ctsDefault = new CancellationTokenSource(TimeOutMilliseconds);

                await cws.SendAsync(
                    WebSocketData.GetBufferFromText(".delay5sec"),
                    WebSocketMessageType.Text,
                    true,
                    ctsDefault.Token);

                var recvBuffer = new byte[100];
                var segment    = new ArraySegment <byte>(recvBuffer);

                Task t = cws.ReceiveAsync(segment, ctsDefault.Token);
                cws.Abort();

                await t;
            }, server);
        }
Esempio n. 10
0
        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);
            }
        }
Esempio n. 11
0
        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 SendAsync(
                    cws,
                    WebSocketData.GetBufferFromText(message),
                    WebSocketMessageType.Text,
                    false,
                    cts.Token);

                Assert.Equal(WebSocketState.Open, cws.State);
                await SendAsync(
                    cws,
                    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 ReceiveAsync(cws, receiveSegment, cts.Token);

                Assert.Equal(WebSocketState.Open, cws.State);
                Assert.Equal(message.Length, recvRet.Count);
                Assert.Equal(WebSocketMessageType.Text, 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));
            }
        }
Esempio n. 12
0
        // This will also pass when no exception is thrown. Current implementation doesn't throw.
        public async Task ReceiveAsync_MultipleOutstandingReceiveOperations_Throws(Uri server)
        {
            using (ClientWebSocket cws = await WebSocketHelper.GetConnectedWebSocket(server, TimeOutMilliseconds, _output))
            {
                var cts = new CancellationTokenSource(TimeOutMilliseconds);

                Task[] tasks = new Task[2];

                await SendAsync(
                    cws,
                    WebSocketData.GetBufferFromText(".delay5sec"),
                    WebSocketMessageType.Text,
                    true,
                    cts.Token);

                var recvBuffer  = new byte[100];
                var recvSegment = new ArraySegment <byte>(recvBuffer);

                try
                {
                    for (int i = 0; i < tasks.Length; i++)
                    {
                        tasks[i] = ReceiveAsync(cws, recvSegment, cts.Token);
                    }

                    await Task.WhenAll(tasks);

                    Assert.Equal(WebSocketState.Open, cws.State);
                }
                catch (Exception ex)
                {
                    if (ex is InvalidOperationException)
                    {
                        Assert.Equal(
                            ResourceHelper.GetExceptionMessage(
                                "net_Websockets_AlreadyOneOutstandingOperation",
                                "ReceiveAsync"),
                            ex.Message);

                        Assert.True(WebSocketState.Aborted == cws.State, cws.State + " state when InvalidOperationException");
                    }
                    else if (ex is WebSocketException)
                    {
                        // Multiple cases.
                        Assert.True(WebSocketState.Aborted == cws.State, cws.State + " state when WebSocketException");

                        WebSocketError errCode = (ex as WebSocketException).WebSocketErrorCode;
                        Assert.True(
                            (errCode == WebSocketError.InvalidState) || (errCode == WebSocketError.Success),
                            "WebSocketErrorCode");
                    }
                    else if (ex is OperationCanceledException)
                    {
                        Assert.True(WebSocketState.Aborted == cws.State, cws.State + " state when OperationCanceledException");
                    }
                    else
                    {
                        Assert.True(false, "Unexpected exception: " + ex.Message);
                    }
                }
            }
        }