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); }
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); } }