public static WebSocket CreateFromStream( Stream stream, bool isServer, string?subProtocol, TimeSpan keepAliveInterval) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (!stream.CanRead || !stream.CanWrite) { throw new ArgumentException(!stream.CanRead ? SR.NotReadableStream : SR.NotWriteableStream, nameof(stream)); } if (subProtocol != null) { WebSocketValidate.ValidateSubprotocol(subProtocol); } if (keepAliveInterval != Timeout.InfiniteTimeSpan && keepAliveInterval < TimeSpan.Zero) { throw new ArgumentOutOfRangeException(nameof(keepAliveInterval), keepAliveInterval, SR.Format(SR.net_WebSockets_ArgumentOutOfRange_TooSmall, 0)); } return(ManagedWebSocket.CreateFromConnectedStream(stream, isServer, subProtocol, keepAliveInterval)); }
public static WebSocket CreateClientWebSocket(Stream innerStream, string subProtocol, int receiveBufferSize, int sendBufferSize, TimeSpan keepAliveInterval, bool useZeroMaskingKey, ArraySegment <byte> internalBuffer) { if (innerStream == null) { throw new ArgumentNullException(nameof(innerStream)); } if (!innerStream.CanRead || !innerStream.CanWrite) { throw new ArgumentException(!innerStream.CanRead ? SR.NotReadableStream : SR.NotWriteableStream, nameof(innerStream)); } if (subProtocol != null) { WebSocketValidate.ValidateSubprotocol(subProtocol); } if (keepAliveInterval != Timeout.InfiniteTimeSpan && keepAliveInterval < TimeSpan.Zero) { throw new ArgumentOutOfRangeException(nameof(keepAliveInterval), keepAliveInterval, SR.Format(SR.net_WebSockets_ArgumentOutOfRange_TooSmall, 0)); } if (receiveBufferSize <= 0 || sendBufferSize <= 0) { throw new ArgumentOutOfRangeException( receiveBufferSize <= 0 ? nameof(receiveBufferSize) : nameof(sendBufferSize), receiveBufferSize <= 0 ? receiveBufferSize : sendBufferSize, SR.Format(SR.net_WebSockets_ArgumentOutOfRange_TooSmall, 0)); } Memory <byte> internalMemoryBuffer = internalBuffer.Count >= receiveBufferSize ? internalBuffer : receiveBufferSize >= ManagedWebSocket.MaxMessageHeaderLength ? new byte[receiveBufferSize] : Memory <byte> .Empty; // let ManagedWebSocket create it return(ManagedWebSocket.CreateFromConnectedStream(innerStream, false, subProtocol, keepAliveInterval, internalMemoryBuffer)); }
public static WebSocket CreateClientWebSocket(Stream innerStream, string subProtocol, int receiveBufferSize, int sendBufferSize, TimeSpan keepAliveInterval, bool useZeroMaskingKey, ArraySegment <byte> internalBuffer) { if (innerStream == null) { throw new ArgumentNullException(nameof(innerStream)); } if (!innerStream.CanRead || !innerStream.CanWrite) { throw new ArgumentException(!innerStream.CanRead ? SR.NotReadableStream : SR.NotWriteableStream, nameof(innerStream)); } if (subProtocol != null) { WebSocketValidate.ValidateSubprotocol(subProtocol); } if (keepAliveInterval != Timeout.InfiniteTimeSpan && keepAliveInterval < TimeSpan.Zero) { throw new ArgumentOutOfRangeException(nameof(keepAliveInterval), keepAliveInterval, SR.Format(SR.net_WebSockets_ArgumentOutOfRange_TooSmall, 0)); } if (receiveBufferSize <= 0 || sendBufferSize <= 0) { throw new ArgumentOutOfRangeException( receiveBufferSize <= 0 ? nameof(receiveBufferSize) : nameof(sendBufferSize), receiveBufferSize <= 0 ? receiveBufferSize : sendBufferSize, SR.Format(SR.net_WebSockets_ArgumentOutOfRange_TooSmall, 0)); } // Ignore useZeroMaskingKey. ManagedWebSocket doesn't currently support that debugging option. // Ignore internalBuffer. ManagedWebSocket uses its own small buffer for headers/control messages. return(ManagedWebSocket.CreateFromConnectedStream(innerStream, false, subProtocol, keepAliveInterval)); }
public async Task ConnectAsyncCore(Uri uri, CancellationToken cancellationToken, ClientWebSocketOptions options) { // TODO: Not currently implemented: // - ClientWebSocketOptions.Credentials // - ClientWebSocketOptions.Proxy // Establish connection to the server CancellationTokenRegistration registration = cancellationToken.Register(s => ((WebSocketHandle)s).Abort(), this); try { // Connect to the remote server Socket connectedSocket = await ConnectSocketAsync(uri.Host, uri.Port, cancellationToken).ConfigureAwait(false); Stream stream = new AsyncEventArgsNetworkStream(connectedSocket); // Upgrade to SSL if needed if (uri.Scheme == UriScheme.Wss) { var sslStream = new SslStream(stream); await sslStream.AuthenticateAsClientAsync( uri.Host, options.ClientCertificates, SecurityProtocol.AllowedSecurityProtocols, checkCertificateRevocation: false).ConfigureAwait(false); stream = sslStream; } // Create the security key and expected response, then build all of the request headers KeyValuePair<string, string> secKeyAndSecWebSocketAccept = CreateSecKeyAndSecWebSocketAccept(); byte[] requestHeader = BuildRequestHeader(uri, options, secKeyAndSecWebSocketAccept.Key); // Write out the header to the connection await stream.WriteAsync(requestHeader, 0, requestHeader.Length, cancellationToken).ConfigureAwait(false); // Parse the response and store our state for the remainder of the connection string subprotocol = await ParseAndValidateConnectResponseAsync(stream, options, secKeyAndSecWebSocketAccept.Value, cancellationToken).ConfigureAwait(false); _webSocket = ManagedWebSocket.CreateFromConnectedStream(stream, false, subprotocol); // If a concurrent Abort or Dispose came in before we set _webSocket, make sure to update it appropriately if (_state == WebSocketState.Aborted) { _webSocket.Abort(); } else if (_state == WebSocketState.Closed) { _webSocket.Dispose(); } } catch (Exception exc) { if (_state < WebSocketState.Closed) { _state = WebSocketState.Closed; } Abort(); if (exc is WebSocketException) { throw; } throw new WebSocketException(SR.net_webstatus_ConnectFailure, exc); } finally { registration.Dispose(); } }
internal static async Task <HttpListenerWebSocketContext> AcceptWebSocketAsyncCore(HttpListenerContext context, string subProtocol, int receiveBufferSize, TimeSpan keepAliveInterval, ArraySegment <byte>?internalBuffer = null) { // get property will create a new response if one doesn't exist. HttpListenerResponse response = context.Response; HttpListenerRequest request = context.Request; ValidateWebSocketHeaders(context); string secWebSocketVersion = request.Headers[HttpKnownHeaderNames.SecWebSocketVersion]; // Optional for non-browser client string origin = request.Headers[HttpKnownHeaderNames.Origin]; string[] secWebSocketProtocols = null; string outgoingSecWebSocketProtocolString; bool shouldSendSecWebSocketProtocolHeader = ProcessWebSocketProtocolHeader( request.Headers[HttpKnownHeaderNames.SecWebSocketProtocol], subProtocol, out outgoingSecWebSocketProtocolString); if (shouldSendSecWebSocketProtocolHeader) { secWebSocketProtocols = new string[] { outgoingSecWebSocketProtocolString }; response.Headers.Add(HttpKnownHeaderNames.SecWebSocketProtocol, outgoingSecWebSocketProtocolString); } // negotiate the websocket key return value string secWebSocketKey = request.Headers[HttpKnownHeaderNames.SecWebSocketKey]; string secWebSocketAccept = HttpWebSocket.GetSecWebSocketAcceptString(secWebSocketKey); response.Headers.Add(HttpKnownHeaderNames.Connection, HttpKnownHeaderNames.Upgrade); response.Headers.Add(HttpKnownHeaderNames.Upgrade, WebSocketUpgradeToken); response.Headers.Add(HttpKnownHeaderNames.SecWebSocketAccept, secWebSocketAccept); response.StatusCode = (int)HttpStatusCode.SwitchingProtocols; // HTTP 101 response.StatusDescription = HttpStatusDescription.Get(HttpStatusCode.SwitchingProtocols); HttpResponseStream responseStream = response.OutputStream as HttpResponseStream; // Send websocket handshake headers await responseStream.WriteWebSocketHandshakeHeadersAsync().ConfigureAwait(false); WebSocket webSocket = ManagedWebSocket.CreateFromConnectedStream(context.Connection.ConnectedStream, true, subProtocol, keepAliveInterval, receiveBufferSize, internalBuffer); HttpListenerWebSocketContext webSocketContext = new HttpListenerWebSocketContext( request.Url, request.Headers, request.Cookies, context.User, request.IsAuthenticated, request.IsLocal, request.IsSecureConnection, origin, secWebSocketProtocols != null ? secWebSocketProtocols : Array.Empty <string>(), secWebSocketVersion, secWebSocketKey, webSocket); return(webSocketContext); }