private void WebSocket(IApplicationBuilder app) { app.Run(async context => { var upgradeFeature = context.Features.Get <IHttpUpgradeFeature>(); // Generate WebSocket response headers string key = context.Request.Headers[Constants.Headers.SecWebSocketKey].ToString(); var responseHeaders = HandshakeHelpers.GenerateResponseHeaders(key); foreach (var headerPair in responseHeaders) { context.Response.Headers[headerPair.Key] = headerPair.Value; } // Upgrade the connection Stream opaqueTransport = await upgradeFeature.UpgradeAsync(); // Get the WebSocket object var ws = WebSocketProtocol.CreateFromStream(opaqueTransport, isServer: true, subProtocol: null, keepAliveInterval: TimeSpan.FromMinutes(2)); var appLifetime = app.ApplicationServices.GetRequiredService <IApplicationLifetime>(); await Echo(ws, appLifetime.ApplicationStopping); }); }
public static async Task ManagedWebSocket_ReceiveUTF8SplitAcrossMultipleBuffers() { // 1 character - 2 bytes byte[] payload = Encoding.UTF8.GetBytes("\u00E6"); var frame = new byte[payload.Length + 2]; frame[0] = 0x81; // FIN = true, Opcode = Text frame[1] = (byte)payload.Length; Array.Copy(payload, 0, frame, 2, payload.Length); using (var stream = new MemoryStream(frame, writable: true)) { WebSocket websocket = WebSocketProtocol.CreateFromStream(stream, false, "null", Timeout.InfiniteTimeSpan); // read first half of the multi-byte character var recvBuffer = new byte[1]; WebSocketReceiveResult result = await websocket.ReceiveAsync(new ArraySegment <byte>(recvBuffer), CancellationToken.None); Assert.False(result.EndOfMessage); Assert.Equal(1, result.Count); Assert.Equal(0xc3, recvBuffer[0]); // read second half of the multi-byte character result = await websocket.ReceiveAsync(new ArraySegment <byte>(recvBuffer), CancellationToken.None); Assert.True(result.EndOfMessage); Assert.Equal(1, result.Count); Assert.Equal(0xa6, recvBuffer[0]); } }
public override async Task ProcessRequestAsync() { DoUpgrade(); await Connection.Transport.Output.FlushAsync(); using (var ws = WebSocketProtocol.CreateFromStream(new DuplexStream(Connection.Transport), isServer: true, subProtocol: null, keepAliveInterval: TimeSpan.FromMinutes(2), new byte[14])) { await ProcessAsync(ws); } }
public static WebSocketPair Create() { // Create streams var serverStream = new DuplexStream(); var clientStream = serverStream.CreateReverseDuplexStream(); return(new WebSocketPair( serverStream, clientStream, clientSocket: WebSocketProtocol.CreateFromStream(clientStream, isServer: false, subProtocol: null, keepAliveInterval: TimeSpan.FromMinutes(2)), serverSocket: WebSocketProtocol.CreateFromStream(serverStream, isServer: true, subProtocol: null, keepAliveInterval: TimeSpan.FromMinutes(2)))); }
public void CreateFromStream_InvalidArguments_Throws() { AssertExtensions.Throws <ArgumentNullException>("stream", () => WebSocketProtocol.CreateFromStream(null, true, "subProtocol", TimeSpan.FromSeconds(30), default(Memory <byte>))); AssertExtensions.Throws <ArgumentException>("stream", () => WebSocketProtocol.CreateFromStream(new MemoryStream(new byte[100], writable: false), true, "subProtocol", TimeSpan.FromSeconds(30), default(Memory <byte>))); AssertExtensions.Throws <ArgumentException>("stream", () => WebSocketProtocol.CreateFromStream(new UnreadableStream(), true, "subProtocol", TimeSpan.FromSeconds(30), default(Memory <byte>))); AssertExtensions.Throws <ArgumentException>("subProtocol", () => WebSocketProtocol.CreateFromStream(new MemoryStream(), true, " ", TimeSpan.FromSeconds(30), default(Memory <byte>))); AssertExtensions.Throws <ArgumentException>("subProtocol", () => WebSocketProtocol.CreateFromStream(new MemoryStream(), true, "\xFF", TimeSpan.FromSeconds(30), default(Memory <byte>))); AssertExtensions.Throws <ArgumentOutOfRangeException>("keepAliveInterval", () => WebSocketProtocol.CreateFromStream(new MemoryStream(), true, "subProtocol", TimeSpan.FromSeconds(-2), default(Memory <byte>))); }
public async Task <WebSocket> AcceptAsync(WebSocketAcceptContext acceptContext) { if (!IsWebSocketRequest) { throw new InvalidOperationException("Not a WebSocket request."); // TODO: LOC } string subProtocol = null; if (acceptContext != null) { subProtocol = acceptContext.SubProtocol; } TimeSpan keepAliveInterval = _options.KeepAliveInterval; int receiveBufferSize = _options.ReceiveBufferSize; var advancedAcceptContext = acceptContext as ExtendedWebSocketAcceptContext; if (advancedAcceptContext != null) { if (advancedAcceptContext.ReceiveBufferSize.HasValue) { receiveBufferSize = advancedAcceptContext.ReceiveBufferSize.Value; } if (advancedAcceptContext.KeepAliveInterval.HasValue) { keepAliveInterval = advancedAcceptContext.KeepAliveInterval.Value; } } string key = string.Join(", ", _context.Request.Headers[Constants.Headers.SecWebSocketKey]); var responseHeaders = HandshakeHelpers.GenerateResponseHeaders(key, subProtocol); foreach (var headerPair in responseHeaders) { _context.Response.Headers[headerPair.Key] = headerPair.Value; } Stream opaqueTransport = await _upgradeFeature.UpgradeAsync(); // Sets status code to 101 // Allocate a buffer for receive (default is 4k) var buffer = new byte[receiveBufferSize]; return(WebSocketProtocol.CreateFromStream(opaqueTransport, isServer: true, subProtocol: subProtocol, keepAliveInterval: keepAliveInterval, buffer: buffer)); }
private static async Task <WebSocket> Upgrade(HttpContext context) { var upgradeFeature = context.Features.Get <IHttpUpgradeFeature>(); // Generate WebSocket response headers string key = context.Request.Headers[Constants.Headers.SecWebSocketKey].ToString(); var responseHeaders = HandshakeHelpers.GenerateResponseHeaders(key); foreach (var headerPair in responseHeaders) { context.Response.Headers[headerPair.Key] = headerPair.Value; } // Upgrade the connection Stream opaqueTransport = await upgradeFeature.UpgradeAsync(); // Get the WebSocket object var ws = WebSocketProtocol.CreateFromStream(opaqueTransport, isServer: true, subProtocol: null, keepAliveInterval: TimeSpan.FromMinutes(2)); return(ws); }
public async Task WebSocketProtocol_CreateFromConnectedStream_Succeeds(Uri echoUri) { Uri uri = new UriBuilder(echoUri) { Scheme = (echoUri.Scheme == "ws") ? "http" : "https" }.Uri; HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, uri); KeyValuePair <string, string> secKeyAndSecWebSocketAccept = CreateSecKeyAndSecWebSocketAccept(); AddWebSocketHeaders(request, secKeyAndSecWebSocketAccept.Key); DirectManagedHttpClientHandler handler = DirectManagedHttpClientHandler.CreateHandler(); using (HttpResponseMessage response = await handler.SendAsync(request, CancellationToken.None).ConfigureAwait(false)) { Assert.Equal(HttpStatusCode.SwitchingProtocols, response.StatusCode); using (Stream connectedStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) { Assert.True(connectedStream.CanRead); Assert.True(connectedStream.CanWrite); using (WebSocket socket = WebSocketProtocol.CreateFromStream(connectedStream, false, null, TimeSpan.FromSeconds(10))) { Assert.NotNull(socket); Assert.Equal(WebSocketState.Open, socket.State); string expected = "Hello World!"; ArraySegment <byte> buffer = new ArraySegment <byte>(Encoding.UTF8.GetBytes(expected)); await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None); buffer = new ArraySegment <byte>(new byte[buffer.Count]); await socket.ReceiveAsync(buffer, CancellationToken.None); Assert.Equal(expected, Encoding.UTF8.GetString(buffer.Array)); } } } }
protected override WebSocket CreateFromStream(Stream stream, bool isServer, string subProtocol, TimeSpan keepAliveInterval) => WebSocketProtocol.CreateFromStream(stream, isServer, subProtocol, keepAliveInterval);
public async Task WebSocketProtocol_CreateFromConnectedStream_Succeeds(Uri echoUri) { using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { bool secure = echoUri.Scheme == "wss"; client.Connect(echoUri.Host, secure ? 443 : 80); Stream stream = new NetworkStream(client, ownsSocket: false); if (secure) { SslStream ssl = new SslStream(stream, leaveInnerStreamOpen: true, delegate { return(true); }); await ssl.AuthenticateAsClientAsync(echoUri.Host); stream = ssl; } using (stream) { using (var writer = new StreamWriter(stream, Encoding.ASCII, bufferSize: 1, leaveOpen: true)) { await writer.WriteAsync($"GET {echoUri.PathAndQuery} HTTP/1.1\r\n"); await writer.WriteAsync($"Host: {echoUri.Host}\r\n"); await writer.WriteAsync($"Upgrade: websocket\r\n"); await writer.WriteAsync($"Connection: Upgrade\r\n"); await writer.WriteAsync($"Sec-WebSocket-Version: 13\r\n"); await writer.WriteAsync($"Sec-WebSocket-Key: {Convert.ToBase64String(Guid.NewGuid().ToByteArray())}\r\n"); await writer.WriteAsync($"\r\n"); } using (var reader = new StreamReader(stream, Encoding.ASCII, detectEncodingFromByteOrderMarks: false, bufferSize: 1, leaveOpen: true)) { string statusLine = await reader.ReadLineAsync(); Assert.NotEmpty(statusLine); Assert.Equal("HTTP/1.1 101 Switching Protocols", statusLine); while (!string.IsNullOrEmpty(await reader.ReadLineAsync())) { ; } } using (WebSocket socket = WebSocketProtocol.CreateFromStream(stream, false, null, TimeSpan.FromSeconds(10))) { Assert.NotNull(socket); Assert.Equal(WebSocketState.Open, socket.State); string expected = "Hello World!"; ArraySegment <byte> buffer = new ArraySegment <byte>(Encoding.UTF8.GetBytes(expected)); await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None); buffer = new ArraySegment <byte>(new byte[buffer.Count]); await socket.ReceiveAsync(buffer, CancellationToken.None); Assert.Equal(expected, Encoding.UTF8.GetString(buffer.Array)); } } } }
public void CreateFromStream_ValidBufferSizes_Succeed(int bufferSize) { Assert.NotNull(WebSocketProtocol.CreateFromStream(new MemoryStream(), false, null, Timeout.InfiniteTimeSpan, new Memory <byte>(new byte[bufferSize]))); Assert.NotNull(WebSocketProtocol.CreateFromStream(new MemoryStream(), true, null, Timeout.InfiniteTimeSpan, new Memory <byte>(new byte[bufferSize]))); }