private async Task NegotiateWebSocket(Socket client)
        {
            WebSocketNegotiationResult result;

            try
            {
                var timeoutTask = Task.Delay(_options.NegotiationTimeout);
#if (NET45 || NET451 || NET452 || NET46)
                Stream stream = new NetworkStream(client, FileAccess.ReadWrite, true);
#elif (DNX451 || DNX452 || DNX46 || NETSTANDARD || UAP10_0 || DOTNET5_4 || NETSTANDARDAPP1_5)
                Stream stream = new NetworkStream(client);
#endif
                foreach (var conExt in _extensions)
                {
                    var extTask = conExt.ExtendConnectionAsync(stream);
                    await Task.WhenAny(timeoutTask, extTask).ConfigureAwait(false);

                    if (timeoutTask.IsCompleted)
                    {
                        throw new WebSocketException("Negotiation timeout (Extension: " + conExt.GetType().Name + ")");
                    }

                    stream = await extTask;
                }

                var handshakeTask = _handShaker.HandshakeAsync(stream);
                await Task.WhenAny(timeoutTask, handshakeTask).ConfigureAwait(false);

                if (timeoutTask.IsCompleted)
                {
                    throw new WebSocketException("Negotiation timeout");
                }

                var handshake = await handshakeTask;

                if (handshake.IsValid)
                {
                    result = new WebSocketNegotiationResult(handshake.Factory.CreateWebSocket(stream, _options, (IPEndPoint)client.LocalEndPoint, (IPEndPoint)client.RemoteEndPoint, handshake.Request, handshake.Response, handshake.NegotiatedMessageExtensions));
                }
                else
                {
                    SafeEnd.Dispose(client);
                    result = new WebSocketNegotiationResult(handshake.Error);
                }
            }
            catch (Exception ex)
            {
                SafeEnd.Dispose(client);
                result = new WebSocketNegotiationResult(ExceptionDispatchInfo.Capture(ex));
            }

            try
            {
                await _negotiations.SendAsync(result, _cancel.Token).ConfigureAwait(false);
            }
            finally
            {
                _semaphore.Release();
            }
        }
Beispiel #2
0
        private async Task NegotiateWebSocket(Socket client)
        {
            await Task.Yield();

            ConfigureSocket(client);

            WebSocketNegotiationResult result;

            try
            {
                var timeoutTask = Task.Delay(_configuration.Options.NegotiationTimeout);
                var stream      = await NegotiateStreamAsync(client, timeoutTask).ConfigureAwait(false);

                var handshake = await HandshakeAsync(stream, timeoutTask).ConfigureAwait(false);

                if (handshake.IsValid)
                {
                    var ws = handshake.Factory.CreateWebSocket(stream, client, _configuration.Options, handshake);
                    result = new WebSocketNegotiationResult(ws);
                }
                else
                {
                    SafeEnd.Dispose(client);
                    result = new WebSocketNegotiationResult(handshake.Error);
                }
            }
            catch (Exception ex)
            {
                SafeEnd.Dispose(client);
                result = new WebSocketNegotiationResult(ExceptionDispatchInfo.Capture(ex));
            }

            await DeliverResultAsync(result).ConfigureAwait(false);
        }
Beispiel #3
0
 private async Task DeliverResultAsync(WebSocketNegotiationResult result)
 {
     try
     {
         await _negotiations.SendAsync(result, _cancel.Token).ConfigureAwait(false);
     }
     finally
     {
         _semaphore.Release();
     }
 }
        private async Task NegotiateWebSocket(Socket client)
        {
            WebSocketNegotiationResult result;
            try
            {
                var timeoutTask = Task.Delay(_options.NegotiationTimeout);
#if (NET45 || NET451 || NET452 || NET46)
                Stream stream = new NetworkStream(client, FileAccess.ReadWrite, true);
#elif (DNX451 || DNX452 || DNX46 || NETSTANDARD || UAP10_0 || DOTNET5_4 || NETSTANDARDAPP1_5)
                Stream stream = new NetworkStream(client);
#endif
                foreach (var conExt in _extensions)
                {
                    var extTask = conExt.ExtendConnectionAsync(stream);
                    await Task.WhenAny(timeoutTask, extTask).ConfigureAwait(false);
                    if (timeoutTask.IsCompleted)
                        throw new WebSocketException("Negotiation timeout (Extension: " + conExt.GetType().Name + ")");

                    stream = await extTask;
                }

                var handshakeTask = _handShaker.HandshakeAsync(stream);
                await Task.WhenAny(timeoutTask, handshakeTask).ConfigureAwait(false);
                if (timeoutTask.IsCompleted)
                    throw new WebSocketException("Negotiation timeout");

                var handshake = await handshakeTask;

                if (handshake.IsValid)
                    result = new WebSocketNegotiationResult(handshake.Factory.CreateWebSocket(stream, _options, (IPEndPoint)client.LocalEndPoint, (IPEndPoint)client.RemoteEndPoint, handshake.Request, handshake.Response, handshake.NegotiatedMessageExtensions));
                else
                {
                    SafeEnd.Dispose(client);
                    result = new WebSocketNegotiationResult(handshake.Error);
                }
            }
            catch (Exception ex)
            {
                SafeEnd.Dispose(client);
                result= new WebSocketNegotiationResult(ExceptionDispatchInfo.Capture(ex));
            }

            try
            {
                await _negotiations.SendAsync(result, _cancel.Token).ConfigureAwait(false);
            }
            finally
            {
                _semaphore.Release();
            }
        }
Beispiel #5
0
        private async Task NegotiateWebSocket(NetworkConnection networkConnection)
        {
            if (networkConnection == null)
            {
                throw new ArgumentNullException(nameof(networkConnection));
            }

            await Task.Yield();

            WebSocketNegotiationResult result;

            try
            {
                var timeoutTask = Task.Delay(_options.NegotiationTimeout);

                foreach (var conExt in _extensions)
                {
                    var extTask = conExt.ExtendConnectionAsync(networkConnection);
                    await Task.WhenAny(timeoutTask, extTask).ConfigureAwait(false);

                    if (timeoutTask.IsCompleted)
                    {
#pragma warning disable 4014
                        extTask.IgnoreFaultOrCancellation(); // make connection exception observed
#pragma warning restore 4014
                        throw new WebSocketException($"Negotiation timeout (Extension: {conExt.GetType().Name})");
                    }

                    networkConnection = await extTask.ConfigureAwait(false);
                }

                var handshakeTask = _handShaker.HandshakeAsync(networkConnection);
                await Task.WhenAny(timeoutTask, handshakeTask).ConfigureAwait(false);

                if (timeoutTask.IsCompleted)
                {
#pragma warning disable 4014
                    handshakeTask.IgnoreFaultOrCancellation(); // make connection exception observed
#pragma warning restore 4014
                    throw new WebSocketException("Negotiation timeout");
                }

                var handshake = await handshakeTask.ConfigureAwait(false);

                if (handshake.IsValidWebSocketRequest)
                {
                    result = new WebSocketNegotiationResult(handshake.Factory.CreateWebSocket(networkConnection, _options, handshake.Request, handshake.Response, handshake.NegotiatedMessageExtensions));
                }
                else if (handshake.IsValidHttpRequest && _options.HttpFallback != null)
                {
                    _options.HttpFallback.Post(handshake.Request, networkConnection);
                    return;
                }
                else
                {
                    SafeEnd.Dispose(networkConnection, this.log);
                    result = new WebSocketNegotiationResult(handshake.Error);
                }

                var webSocket = result.Result;
                if (_negotiations.TryEnqueue(result) == false)
                {
                    SafeEnd.Dispose(webSocket);
                    return; // too many negotiations
                }

                if (webSocket != null)
                {
                    this.pingQueue?.GetSubscriptionList().Add(webSocket);
                }
            }
            catch (Exception negotiationError)
            {
                if (this.log.IsDebugEnabled)
                {
                    this.log.Debug("An error occurred while negotiating WebSocket request.", negotiationError);
                }

                SafeEnd.Dispose(networkConnection, this.log);
                result = new WebSocketNegotiationResult(ExceptionDispatchInfo.Capture(negotiationError));
            }
            finally
            {
                _semaphore.Release();
            }
        }