public async Task CanSendAndReceiveCompressedData() { await using (var server = KestrelWebSocketHelpers.CreateServer(LoggerFactory, out var port, async context => { Assert.True(context.WebSockets.IsWebSocketRequest); using var webSocket = await context.WebSockets.AcceptWebSocketAsync(new WebSocketAcceptContext() { DangerousEnableCompression = true, ServerMaxWindowBits = 13 }); var serverBuffer = new byte[1024]; while (true) { var result = await webSocket.ReceiveAsync(serverBuffer, CancellationToken.None); if (result.MessageType == WebSocketMessageType.Close) { break; } await webSocket.SendAsync(serverBuffer.AsMemory(0, result.Count), result.MessageType, result.EndOfMessage, default); } await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, null, default); })) { using (var client = new ClientWebSocket()) { client.Options.DangerousDeflateOptions = new WebSocketDeflateOptions() { ServerMaxWindowBits = 12, ClientMaxWindowBits = 11, }; await client.ConnectAsync(new Uri($"ws://127.0.0.1:{port}/"), CancellationToken.None); var sendCount = 8193; var clientBuf = new byte[sendCount]; var receiveBuf = new byte[sendCount]; Random.Shared.NextBytes(clientBuf); await client.SendAsync(clientBuf.AsMemory(0, sendCount), WebSocketMessageType.Binary, true, default); var totalRecv = 0; while (totalRecv < sendCount) { var result = await client.ReceiveAsync(receiveBuf.AsMemory(totalRecv), default); totalRecv += result.Count; if (result.EndOfMessage) { Assert.Equal(sendCount, totalRecv); for (var i = 0; i < sendCount; ++i) { Assert.True(clientBuf[i] == receiveBuf[i], $"offset {i} not equal: {clientBuf[i]} == {receiveBuf[i]}"); } } } await client.CloseAsync(WebSocketCloseStatus.NormalClosure, null, default); } } }
public async Task SendFragmentedData_Success() { var orriginalData = Encoding.UTF8.GetBytes("Hello World"); var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); await using (var server = KestrelWebSocketHelpers.CreateServer(LoggerFactory, out var port, async context => { Assert.True(context.WebSockets.IsWebSocketRequest); var webSocket = await context.WebSockets.AcceptWebSocketAsync(); var serverBuffer = new byte[orriginalData.Length]; var result = await webSocket.ReceiveAsync(new ArraySegment <byte>(serverBuffer), CancellationToken.None); Assert.False(result.EndOfMessage); Assert.Equal(2, result.Count); int totalReceived = result.Count; Assert.Equal(WebSocketMessageType.Binary, result.MessageType); tcs.SetResult(); result = await webSocket.ReceiveAsync( new ArraySegment <byte>(serverBuffer, totalReceived, serverBuffer.Length - totalReceived), CancellationToken.None); Assert.False(result.EndOfMessage); Assert.Equal(2, result.Count); totalReceived += result.Count; Assert.Equal(WebSocketMessageType.Binary, result.MessageType); tcs.SetResult(); result = await webSocket.ReceiveAsync( new ArraySegment <byte>(serverBuffer, totalReceived, serverBuffer.Length - totalReceived), CancellationToken.None); Assert.True(result.EndOfMessage); Assert.Equal(7, result.Count); totalReceived += result.Count; Assert.Equal(WebSocketMessageType.Binary, result.MessageType); Assert.Equal(orriginalData, serverBuffer); })) { using (var client = new ClientWebSocket()) { await client.ConnectAsync(new Uri($"ws://127.0.0.1:{port}/"), CancellationToken.None); await client.SendAsync(new ArraySegment <byte>(orriginalData, 0, 2), WebSocketMessageType.Binary, false, CancellationToken.None); await tcs.Task; tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); await client.SendAsync(new ArraySegment <byte>(orriginalData, 2, 2), WebSocketMessageType.Binary, false, CancellationToken.None); await tcs.Task; tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); await client.SendAsync(new ArraySegment <byte>(orriginalData, 4, 7), WebSocketMessageType.Binary, true, CancellationToken.None); } } }
public async Task Connect_Success() { await using (var server = KestrelWebSocketHelpers.CreateServer(LoggerFactory, out var port, async context => { Assert.True(context.WebSockets.IsWebSocketRequest); var webSocket = await context.WebSockets.AcceptWebSocketAsync(); })) { using (var client = new ClientWebSocket()) { await client.ConnectAsync(new Uri($"ws://127.0.0.1:{port}/"), CancellationToken.None); } } }
public async Task CommonHeadersAreSetToInternedStrings() { await using (var server = KestrelWebSocketHelpers.CreateServer(LoggerFactory, out var port, async context => { Assert.True(context.WebSockets.IsWebSocketRequest); var webSocket = await context.WebSockets.AcceptWebSocketAsync(); // Use ReferenceEquals and test against the constants Assert.Same(HeaderNames.Upgrade, context.Request.Headers.Connection.ToString()); Assert.Same(Constants.Headers.UpgradeWebSocket, context.Request.Headers.Upgrade.ToString()); Assert.Same(Constants.Headers.SupportedVersion, context.Request.Headers.SecWebSocketVersion.ToString()); })) { using (var client = new ClientWebSocket()) { await client.ConnectAsync(new Uri($"ws://127.0.0.1:{port}/"), CancellationToken.None); } } }
public async Task OriginIsValidatedForWebSocketRequests(HttpStatusCode expectedCode, params string[] origins) { await using (var server = KestrelWebSocketHelpers.CreateServer(LoggerFactory, out var port, context => { Assert.True(context.WebSockets.IsWebSocketRequest); return(Task.CompletedTask); }, o => { if (origins != null) { foreach (var origin in origins) { o.AllowedOrigins.Add(origin); } } })) { using (var client = new HttpClient()) { var uri = new UriBuilder(new Uri($"ws://127.0.0.1:{port}/")); uri.Scheme = "http"; // Craft a valid WebSocket Upgrade request using (var request = new HttpRequestMessage(HttpMethod.Get, uri.ToString())) { request.Headers.Connection.Clear(); request.Headers.Connection.Add("Upgrade"); request.Headers.Upgrade.Add(new System.Net.Http.Headers.ProductHeaderValue("websocket")); request.Headers.Add(HeaderNames.SecWebSocketVersion, "13"); // SecWebSocketKey required to be 16 bytes request.Headers.Add(HeaderNames.SecWebSocketKey, Convert.ToBase64String(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, Base64FormattingOptions.None)); request.Headers.Add(HeaderNames.Origin, "http://example.com"); var response = await client.SendAsync(request); Assert.Equal(expectedCode, response.StatusCode); } } } }
public async Task CloseFromCloseReceived_Success() { string closeDescription = "Test Closed"; await using (var server = KestrelWebSocketHelpers.CreateServer(LoggerFactory, out var port, async context => { Assert.True(context.WebSockets.IsWebSocketRequest); var webSocket = await context.WebSockets.AcceptWebSocketAsync(); await webSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, closeDescription, CancellationToken.None); var serverBuffer = new byte[1024]; var result = await webSocket.ReceiveAsync(new ArraySegment <byte>(serverBuffer), CancellationToken.None); Assert.True(result.EndOfMessage); Assert.Equal(0, result.Count); Assert.Equal(WebSocketMessageType.Close, result.MessageType); Assert.Equal(WebSocketCloseStatus.NormalClosure, result.CloseStatus); Assert.Equal(closeDescription, result.CloseStatusDescription); })) { using (var client = new ClientWebSocket()) { await client.ConnectAsync(new Uri($"ws://127.0.0.1:{port}/"), CancellationToken.None); var clientBuffer = new byte[1024]; var result = await client.ReceiveAsync(new ArraySegment <byte>(clientBuffer), CancellationToken.None); Assert.True(result.EndOfMessage); Assert.Equal(0, result.Count); Assert.Equal(WebSocketMessageType.Close, result.MessageType); Assert.Equal(WebSocketCloseStatus.NormalClosure, result.CloseStatus); Assert.Equal(closeDescription, result.CloseStatusDescription); Assert.Equal(WebSocketState.CloseReceived, client.State); await client.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None); Assert.Equal(WebSocketState.Closed, client.State); } } }
public async Task SendEmptyData_Success() { await using (var server = KestrelWebSocketHelpers.CreateServer(LoggerFactory, out var port, async context => { Assert.True(context.WebSockets.IsWebSocketRequest); var webSocket = await context.WebSockets.AcceptWebSocketAsync(); var serverBuffer = new byte[0]; var result = await webSocket.ReceiveAsync(new ArraySegment <byte>(serverBuffer), CancellationToken.None); Assert.True(result.EndOfMessage); Assert.Equal(0, result.Count); Assert.Equal(WebSocketMessageType.Binary, result.MessageType); })) { using (var client = new ClientWebSocket()) { await client.ConnectAsync(new Uri($"ws://127.0.0.1:{port}/"), CancellationToken.None); var orriginalData = new byte[0]; await client.SendAsync(new ArraySegment <byte>(orriginalData), WebSocketMessageType.Binary, true, CancellationToken.None); } } }