private void SendClosingHandshake(NetworkStream stream, WebSocketStatusCode statusCode = WebSocketStatusCode.Closure) { var response = new byte[4]; response[0] = 136; if (statusCode == WebSocketStatusCode.ProtocolError) { response[1] = 8; // status code 1002 over 2 bytes response[2] = 3; response[3] = 234; } stream.Write(response, 0, response.Length); }
public WebSocketException(WebSocketStatusCode statusCode) { _statusCode = statusCode; }
public WebSocketException(WebSocketStatusCode statusCode, string message) : base(message) { _statusCode = statusCode; }
private void ReadCallback(IAsyncResult asyncResult) { if (client.Connected == false || stream == null || stream.CanRead == false) { Close(); return; } int didRead = stream.EndRead(asyncResult); Console.WriteLine("didRead: " + didRead); byteBuffer.Write(tempBuffer, 0, didRead); if (IsReady == false) { if (HandleSetUpPhase() == false) { // Send "bad request" byte[] response = Encoding.UTF8.GetBytes("HTTP/1.1 400" + httpEOL + httpEOL); stream.Write(response); Close(); return; } } else { byte[] data = byteBuffer.GetBufferBytesCopy(); Console.WriteLine("Received " + data.Length + " bytes"); byte[] decodedData = DecodeData(data, out bool isFinal, out WebSocketOpCode rcvOpcode); if (decodedData == null) { // Unable to decode (e.g. not masked) -> Close connection Close(); return; } bool isControl = rcvOpcode == WebSocketOpCode.Close || rcvOpcode == WebSocketOpCode.Ping || rcvOpcode == WebSocketOpCode.Pong; if (isControl) { if (isFinal == false) { // Control messages cannot be fragmented Console.WriteLine("ERROR: Received fragmented control message -> Close"); Close(); return; } Console.WriteLine($"Received control message of type '{rcvOpcode}' with length {decodedData.Length}"); if (rcvOpcode == WebSocketOpCode.Close) { if (decodedData.Length >= 2) { WebSocketStatusCode code = (WebSocketStatusCode)(decodedData[0] << 8 | decodedData[1]); string reason = "unknown"; if (decodedData.Length > 2) { reason = Encoding.UTF8.GetString(decodedData, 2, decodedData.Length - 2); } Console.WriteLine("Received close frame - code: " + code + " -- reason: " + reason); } // Close() will send a close frame if necessary Close(); return; } } else { if (isFinal == true && receiveFragmentBuffer.Length == 0) { // If this is a "final" block and we have no previously // buffered fragments, we can send this block directly // to upstream. OnDidRead?.Invoke(decodedData.AsSpan()); } else { // Cache received data until we receive the final frame receiveFragmentBuffer.Write(decodedData); if (isFinal == true) { OnDidRead?.Invoke(receiveFragmentBuffer.GetBufferBytesCopy().AsSpan()); receiveFragmentBuffer.Clear(true); } } } byteBuffer.Clear(); } if (IsReady) { // Only try to read if we're still ready stream.BeginRead(tempBuffer, 0, tempBuffer.Length, ReadCallback, null); } }
public byte[] FrameClose(WebSocketStatusCode code) { return FrameData(((int)code).ToBigEndianBytes<ushort>(), FrameType.Close); }
internal ProtocolException(WebSocketStatusCode statusCode) { StatusCode = statusCode; }
public ProtocolException(string p, WebSocketStatusCode webSocketStatusCode) : base(p) { StatusCode = webSocketStatusCode; }
public static Task Close(this ISocketListener socketListener, ILogger logger, IHandler handler, WebSocketStatusCode code = WebSocketStatusCode.NormalClosure) { var message = handler.FrameClose(code); return socketListener.Send(message, socketListener.Dispose, ex => logger.Error("Error sending close frame: {0}", ex)); }