public async Task <WebSocket> ConnectAsync(Uri uri, CancellationToken cancellationToken) { WebSocketFeature webSocketFeature = null; var contextBuilder = new HttpContextBuilder(_application, AllowSynchronousIO, PreserveExecutionContext); contextBuilder.Configure(context => { var request = context.Request; var scheme = uri.Scheme; scheme = (scheme == "ws") ? "http" : scheme; scheme = (scheme == "wss") ? "https" : scheme; request.Scheme = scheme; if (!request.Host.HasValue) { request.Host = uri.IsDefaultPort ? new HostString(HostString.FromUriComponent(uri).Host) : HostString.FromUriComponent(uri); } request.Path = PathString.FromUriComponent(uri); request.PathBase = PathString.Empty; if (request.Path.StartsWithSegments(_pathBase, out var remainder)) { request.Path = remainder; request.PathBase = _pathBase; } request.QueryString = QueryString.FromUriComponent(uri); request.Headers.Add(HeaderNames.Connection, new string[] { "Upgrade" }); request.Headers.Add(HeaderNames.Upgrade, new string[] { "websocket" }); request.Headers.Add(HeaderNames.SecWebSocketVersion, new string[] { "13" }); request.Headers.Add(HeaderNames.SecWebSocketKey, new string[] { CreateRequestKey() }); if (SubProtocols.Any()) { request.Headers.Add(HeaderNames.SecWebSocketProtocol, SubProtocols.ToArray()); } request.Body = Stream.Null; // WebSocket webSocketFeature = new WebSocketFeature(context); context.Features.Set <IHttpWebSocketFeature>(webSocketFeature); ConfigureRequest?.Invoke(context.Request); }); var httpContext = await contextBuilder.SendAsync(cancellationToken); if (httpContext.Response.StatusCode != StatusCodes.Status101SwitchingProtocols) { throw new InvalidOperationException("Incomplete handshake, status code: " + httpContext.Response.StatusCode); } if (webSocketFeature.ClientWebSocket == null) { throw new InvalidOperationException("Incomplete handshake"); } return(webSocketFeature.ClientWebSocket); }
public async Task <GameSocket> ConnectAsync(Uri uri, CancellationToken cancellationToken) { GameSocketFeature gameSocketFeature = null; var contextBuilder = new ProtoContextBuilder(_application, AllowSynchronousIO); contextBuilder.Configure(context => { var request = context.Request; var scheme = uri.Scheme; scheme = (scheme == "ws") ? "http" : scheme; scheme = (scheme == "wss") ? "https" : scheme; request.Scheme = scheme; request.Path = PathString.FromUriComponent(uri); request.PathBase = PathString.Empty; if (request.Path.StartsWithSegments(_pathBase, out var remainder)) { request.Path = remainder; request.PathBase = _pathBase; } request.QueryString = QueryString.FromUriComponent(uri); request.Headers.Add("Connection", new string[] { "Upgrade" }); request.Headers.Add("Upgrade", new string[] { "gamesocket" }); request.Headers.Add("Sec-GameSocket-Version", new string[] { "13" }); request.Headers.Add("Sec-GameSocket-Key", new string[] { CreateRequestKey() }); request.Body = Stream.Null; // GameSocket gameSocketFeature = new GameSocketFeature(context); context.Features.Set <IProtoGameSocketFeature>(gameSocketFeature); ConfigureRequest?.Invoke(context.Request); }); var httpContext = await contextBuilder.SendAsync(cancellationToken); if (httpContext.Response.StatusCode != StatusCodes.Status101SwitchingProtocols) { throw new InvalidOperationException("Incomplete handshake, status code: " + httpContext.Response.StatusCode); } if (gameSocketFeature.ClientGameSocket == null) { throw new InvalidOperationException("Incomplete handshake"); } return(gameSocketFeature.ClientGameSocket); }
public async Task <WebSocket> ConnectAsync(Uri uri, CancellationToken cancellationToken) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); var cancellation = cancellationToken.Register(() => request.Abort()); request.Headers[Constants.Headers.SecWebSocketVersion] = Constants.Headers.SupportedVersion; if (SubProtocols.Count > 0) { request.Headers[Constants.Headers.SecWebSocketProtocol] = string.Join(", ", SubProtocols); } ConfigureRequest?.Invoke(request); HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync(); cancellation.Dispose(); InspectResponse?.Invoke(response); // TODO: Validate handshake HttpStatusCode statusCode = response.StatusCode; if (statusCode != HttpStatusCode.SwitchingProtocols) { response.Dispose(); throw new InvalidOperationException("Incomplete handshake, invalid status code: " + statusCode); } // TODO: Validate Sec-WebSocket-Key/Sec-WebSocket-Accept string subProtocol = response.Headers[Constants.Headers.SecWebSocketProtocol]; if (!string.IsNullOrEmpty(subProtocol) && !SubProtocols.Contains(subProtocol, StringComparer.OrdinalIgnoreCase)) { throw new InvalidOperationException("Incomplete handshake, the server specified an unknown sub-protocol: " + subProtocol); } var stream = response.GetResponseStream(); return(CommonWebSocket.CreateClientWebSocket(stream, subProtocol, KeepAliveInterval, ReceiveBufferSize, UseZeroMask)); }