private async void HandleHTTPResponse()
        {
            // STEP 6: Read and parse the HTTP response
            WriteLog.To.Sync.V(Tag, "WebSocket sent HTTP request...");
            try {
                using (var streamReader = new StreamReader(NetworkStream, Encoding.ASCII, false, 5, true)) {
                    var parser = new HttpMessageParser(await streamReader.ReadLineAsync().ConfigureAwait(false));
                    while (true)
                    {
                        var line = await streamReader.ReadLineAsync().ConfigureAwait(false);

                        if (String.IsNullOrEmpty(line))
                        {
                            break;
                        }

                        parser.Append(line);
                    }

                    ReceivedHttpResponse(parser);
                }
            } catch (Exception e) {
                WriteLog.To.Sync.I(Tag, "Error reading HTTP response of websocket handshake", e);
                DidClose(e);
            }
        }
        private unsafe void ReceivedHttpResponse([NotNull] HttpMessageParser parser)
        {
            // STEP 7: Determine if the HTTP response was a success
            _logic.ReceivedResponse(parser);
            var httpStatus = _logic.HttpStatus;

            if (_logic.ShouldRetry)
            {
                // Usually authentication needed, or a redirect
                ResetConnections();
                Start();
                return;
            }

            var socket = _socket;

            _c4Queue.DispatchAsync(() =>
            {
                var dict = parser.Headers?.ToDictionary(x => x.Key, x => (object)x.Value) ?? new Dictionary <string, object>();
                Native.c4socket_gotHTTPResponse(socket, httpStatus, dict);
            });

            // Success is a 101 response, anything else is not good
            if (_logic.Error != null)
            {
                DidClose(_logic.Error);
            }
            else if (httpStatus != 101)
            {
                var closeCode = C4WebSocketCloseCode.WebSocketClosePolicyError;
                if (httpStatus >= 300 && httpStatus < 1000)
                {
                    closeCode = (C4WebSocketCloseCode)httpStatus;
                }

                var reason = parser.Reason;
                DidClose(closeCode, reason);
            }
            else if (!CheckHeader(parser, "Connection", "Upgrade", false))
            {
                DidClose(C4WebSocketCloseCode.WebSocketCloseProtocolError, "Invalid 'Connection' header");
            }
            else if (!CheckHeader(parser, "Upgrade", "websocket", false))
            {
                DidClose(C4WebSocketCloseCode.WebSocketCloseProtocolError, "Invalid 'Upgrade' header");
            }
            else if (!CheckHeader(parser, "Sec-WebSocket-Accept", _expectedAcceptHeader, true))
            {
                DidClose(C4WebSocketCloseCode.WebSocketCloseProtocolError, "Invalid 'Sec-WebSocket-Accept' header");
            }
            else
            {
                Connected();
            }
        }
        private static bool CheckHeader([NotNull] HttpMessageParser parser, [NotNull] string key, string expectedValue, bool caseSens)
        {
            string value = null;

            if (parser.Headers?.TryGetValue(key, out value) != true)
            {
                return(false);
            }

            var comparison = caseSens ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;

            return(value?.Equals(expectedValue, comparison) == true);
        }
Esempio n. 4
0
        private async void HandleHTTPResponse()
        {
            Log.To.Sync.V(Tag, "WebSocket sent HTTP request...");

            using (var streamReader = new StreamReader(NetworkStream, Encoding.ASCII, false, 5, true)) {
                var parser = new HttpMessageParser(await streamReader.ReadLineAsync().ConfigureAwait(false));
                while (true)
                {
                    var line = await streamReader.ReadLineAsync().ConfigureAwait(false);

                    if (String.IsNullOrEmpty(line))
                    {
                        break;
                    }

                    parser.Append(line);
                }

                ReceivedHttpResponse(parser);
            }
        }