Exemplo n.º 1
0
 public void CreateResponseKey()
 {
     foreach (var key in _requestKeys)
     {
         HandshakeHelpers.CreateResponseKey(key);
     }
 }
Exemplo n.º 2
0
 public void IsRequestKeyValid()
 {
     foreach (var key in _requestKeys)
     {
         HandshakeHelpers.IsRequestKeyValid(key);
     }
 }
Exemplo n.º 3
0
            public async Task <MazeSocket> AcceptAsync()
            {
                var key = string.Join(", ", _context.Request.Headers[MazeSocketHeaders.SecWebSocketKey]);

                var responseHeaders = HandshakeHelpers.GenerateResponseHeaders(key);

                foreach (var headerPair in responseHeaders)
                {
                    _context.Response.Headers[headerPair.Key] = headerPair.Value;
                }

                var stream = await _upgradeFeature.UpgradeAsync();

                await Task.Delay(500);

                string result;

                using (var streamReader = new StreamReader(stream))
                {
                    result = await streamReader.ReadLineAsync();
                }

                Debug.Print("Result Server: " + result);

                using (var streamWriter = new StreamWriter(stream))
                {
                    await streamWriter.WriteLineAsync("Hey other");
                }
                return(new MazeSocket(stream, _options.KeepAliveInterval));
            }
Exemplo n.º 4
0
            public async Task <WebSocket> AcceptAsync(GameSocketAcceptContext acceptContext)
            {
                if (!IsGameSocketRequest)
                {
                    throw new InvalidOperationException("Not a WebSocket request."); // TODO: LOC
                }
                var subProtocol       = acceptContext?.SubProtocol;
                var keepAliveInterval = _options.KeepAliveInterval;
                var receiveBufferSize = _options.ReceiveBufferSize;

                if (acceptContext is ExtendedGameSocketAcceptContext advancedAcceptContext)
                {
                    if (advancedAcceptContext.ReceiveBufferSize.HasValue)
                    {
                        receiveBufferSize = advancedAcceptContext.ReceiveBufferSize.Value;
                    }
                    if (advancedAcceptContext.KeepAliveInterval.HasValue)
                    {
                        keepAliveInterval = advancedAcceptContext.KeepAliveInterval.Value;
                    }
                }

                var key = string.Join(", ", _context.Request.Headers[Constants.Headers.SecGameSocketKey]);

                HandshakeHelpers.GenerateResponseHeaders(key, subProtocol, _context.Response.Headers);

                var opaqueTransport = await _upgradeFeature.UpgradeAsync(); // Sets status code to 101

                return(WebSocket.CreateFromStream(opaqueTransport, isServer: true, subProtocol: subProtocol, keepAliveInterval: keepAliveInterval));
            }
Exemplo n.º 5
0
        public static bool CheckSupportedWebSocketRequest(string method, IHeaderDictionary requestHeaders)
        {
            if (!HttpMethods.IsGet(method))
            {
                return(false);
            }

            if (!CheckWebSocketVersion(requestHeaders))
            {
                return(false);
            }

            var foundHeader = false;

            var values = requestHeaders.GetCommaSeparatedValues(HeaderNames.Upgrade);

            foreach (var value in values)
            {
                if (string.Equals(value, Constants.Headers.UpgradeWebSocket, StringComparison.OrdinalIgnoreCase))
                {
                    // WebSockets are long lived; so if the header values are valid we switch them out for the interned versions.
                    if (values.Length == 1)
                    {
                        requestHeaders.Upgrade = Constants.Headers.UpgradeWebSocket;
                    }
                    foundHeader = true;
                    break;
                }
            }
            if (!foundHeader)
            {
                return(false);
            }
            foundHeader = false;

            values = requestHeaders.GetCommaSeparatedValues(HeaderNames.Connection);
            foreach (var value in values)
            {
                if (string.Equals(value, HeaderNames.Upgrade, StringComparison.OrdinalIgnoreCase))
                {
                    // WebSockets are long lived; so if the header values are valid we switch them out for the interned versions.
                    if (values.Length == 1)
                    {
                        requestHeaders.Connection = HeaderNames.Upgrade;
                    }
                    foundHeader = true;
                    break;
                }
            }
            if (!foundHeader)
            {
                return(false);
            }

            return(HandshakeHelpers.IsRequestKeyValid(requestHeaders.SecWebSocketKey.ToString()));
        }
Exemplo n.º 6
0
        public void CreatesCorrectResponseKey()
        {
            // Example taken from https://tools.ietf.org/html/rfc6455#section-1.3
            var key = "dGhlIHNhbXBsZSBub25jZQ==";
            var expectedResponse = "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=";

            var response = HandshakeHelpers.CreateResponseKey(key);

            Assert.Equal(expectedResponse, response);
        }
            public async Task <WebSocket> AcceptAsync(IWebSocketAcceptContext 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 WebSocketAcceptContext;

                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

                return(CommonWebSocket.CreateServerWebSocket(opaqueTransport, subProtocol, keepAliveInterval, receiveBufferSize));
            }
Exemplo n.º 8
0
        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 = WebSocket.CreateFromStream(opaqueTransport, isServer: true, subProtocol: null, keepAliveInterval: TimeSpan.FromMinutes(2));

            return(ws);
        }
Exemplo n.º 9
0
        private bool IsMazeSocketRequest(HttpContext context, IHttpUpgradeFeature upgradeFeature)
        {
            if (!upgradeFeature.IsUpgradableRequest)
            {
                return(false);
            }

            if (!string.Equals(context.Request.Method, "GET", StringComparison.OrdinalIgnoreCase))
            {
                return(false);
            }

            var headers = new List <KeyValuePair <string, string> >();

            foreach (var headerName in HandshakeHelpers.NeededHeaders)
            {
                foreach (var value in context.Request.Headers.GetCommaSeparatedValues(headerName))
                {
                    headers.Add(new KeyValuePair <string, string>(headerName, value));
                }
            }

            return(HandshakeHelpers.CheckSupportedRequest(headers));
        }
Exemplo n.º 10
0
 public void CompressionNegotiateNotAccepted(string clientHeader)
 {
     Assert.False(HandshakeHelpers.ParseDeflateOptions(clientHeader.AsSpan(), serverContextTakeover: true, serverMaxWindowBits: 15,
                                                       out var _, out var response));
 }
Exemplo n.º 11
0
 public void CompressionNegotiationProducesCorrectHeaderWithCustomOptions(string clientHeader, string expectedResponse)
 {
     Assert.True(HandshakeHelpers.ParseDeflateOptions(clientHeader.AsSpan(), serverContextTakeover: false, serverMaxWindowBits: 14,
                                                      out var _, out var response));
     Assert.Equal(expectedResponse, response);
 }
Exemplo n.º 12
0
 public void RejectsInvalidRequestKeys(string key)
 {
     Assert.False(HandshakeHelpers.IsRequestKeyValid(key));
 }
Exemplo n.º 13
0
 public void AcceptsValidRequestKeys(string key)
 {
     Assert.True(HandshakeHelpers.IsRequestKeyValid(key));
 }
Exemplo n.º 14
0
        public async Task <WebSocket> AcceptAsync(WebSocketAcceptContext acceptContext)
        {
            if (!IsWebSocketRequest)
            {
                throw new InvalidOperationException("Not a WebSocket request.");
            }

            string?  subProtocol           = null;
            bool     enableCompression     = false;
            bool     serverContextTakeover = true;
            int      serverMaxWindowBits   = 15;
            TimeSpan keepAliveInterval     = _options.KeepAliveInterval;

            if (acceptContext != null)
            {
                subProtocol           = acceptContext.SubProtocol;
                enableCompression     = acceptContext.DangerousEnableCompression;
                serverContextTakeover = !acceptContext.DisableServerContextTakeover;
                serverMaxWindowBits   = acceptContext.ServerMaxWindowBits;
                keepAliveInterval     = acceptContext.KeepAliveInterval ?? keepAliveInterval;
            }

#pragma warning disable CS0618 // Type or member is obsolete
            if (acceptContext is ExtendedWebSocketAcceptContext advancedAcceptContext)
#pragma warning restore CS0618 // Type or member is obsolete
            {
                if (advancedAcceptContext.KeepAliveInterval.HasValue)
                {
                    keepAliveInterval = advancedAcceptContext.KeepAliveInterval.Value;
                }
            }

            HandshakeHelpers.GenerateResponseHeaders(!_isH2WebSocket, _context.Request.Headers, subProtocol, _context.Response.Headers);

            WebSocketDeflateOptions?deflateOptions = null;
            if (enableCompression)
            {
                var ext = _context.Request.Headers.SecWebSocketExtensions;
                if (ext.Count != 0)
                {
                    // loop over each extension offer, extensions can have multiple offers, we can accept any
                    foreach (var extension in _context.Request.Headers.GetCommaSeparatedValues(HeaderNames.SecWebSocketExtensions))
                    {
                        if (extension.AsSpan().TrimStart().StartsWith("permessage-deflate", StringComparison.Ordinal))
                        {
                            if (HandshakeHelpers.ParseDeflateOptions(extension.AsSpan().TrimStart(), serverContextTakeover, serverMaxWindowBits, out var parsedOptions, out var response))
                            {
                                Log.CompressionAccepted(_logger, response);
                                deflateOptions = parsedOptions;
                                // If more extension types are added, this would need to be a header append
                                // and we wouldn't want to break out of the loop
                                _context.Response.Headers.SecWebSocketExtensions = response;
                                break;
                            }
                        }
                    }

                    if (deflateOptions is null)
                    {
                        Log.CompressionNotAccepted(_logger);
                    }
                }
            }

            Stream opaqueTransport;
            // HTTP/2
            if (_isH2WebSocket)
            {
                // Send the response headers
                opaqueTransport = await _connectFeature !.AcceptAsync();
            }
            // HTTP/1.1
            else
            {
                opaqueTransport = await _upgradeFeature !.UpgradeAsync(); // Sets status code to 101
            }

            return(WebSocket.CreateFromStream(opaqueTransport, new WebSocketCreationOptions()
            {
                IsServer = true,
                KeepAliveInterval = keepAliveInterval,
                SubProtocol = subProtocol,
                DangerousDeflateOptions = deflateOptions
            }));
        }