protected void NegotiateInboundRFC6455(byte[] data, int numberOfBytes) { if (_QueuedBytes != null) { MemoryStream MS = new MemoryStream(); MS.Write(_QueuedBytes, 0, _QueuedBytes.Length); MS.Write(data, 0, data.Length); data = MS.ToArray(); numberOfBytes = data.Length; _QueuedBytes = null; } for (int i = 0; i < numberOfBytes; i++) { // Check what the client packet state is switch (_State) { case WebSocketNegotiationState.NeedPacketStart: // Next byte will give us the opcode, and also tell is if the message is fragmented _FrameMask = new byte[4]; _FrameOpCode = data[i]; _FramePayloadLength = 0; _FramePayloadReceived = 0; _State = WebSocketNegotiationState.NeedPayloadLength; break; case WebSocketNegotiationState.NeedPayloadLength: _FramePayloadLength = (data[i] & 0x7F); if (_FramePayloadLength <= 125) { _State = WebSocketNegotiationState.NeedMaskingKey; } else if (_FramePayloadLength == 126) { if (i < (numberOfBytes - 2)) { byte[] Bytes = new byte[] { data[++i], data[++i] }; _FramePayloadLength = BitConverter.ToInt16(Bytes, 0); _State = WebSocketNegotiationState.NeedMaskingKey; } else { List<byte> LeftoverBytes = new List<byte>(); while (i < numberOfBytes) LeftoverBytes.Add(data[i++]); _QueuedBytes = LeftoverBytes.ToArray(); } } else if (_FramePayloadLength == 127) { if (i < (numberOfBytes - 8)) { byte[] Bytes = new byte[] { data[++i], data[++i], data[++i], data[++i], data[++i], data[++i], data[++i], data[++i] }; _FramePayloadLength = BitConverter.ToInt64(Bytes, 0); _State = WebSocketNegotiationState.NeedMaskingKey; } else { List<byte> LeftoverBytes = new List<byte>(); while (i < numberOfBytes) LeftoverBytes.Add(data[i++]); _QueuedBytes = LeftoverBytes.ToArray(); } } break; case WebSocketNegotiationState.NeedMaskingKey: if (i < (numberOfBytes - 3)) { byte[] Bytes = new byte[] { data[i], data[++i], data[++i], data[++i] }; int TempMask = BitConverter.ToInt32(Bytes, 0); _FrameMask[3] = (byte)((TempMask & 0xFF000000) >> 24); _FrameMask[2] = (byte)((TempMask & 0x00FF0000) >> 16); _FrameMask[1] = (byte)((TempMask & 0x0000FF00) >> 8); _FrameMask[0] = (byte)(TempMask & 0x000000FF); _State = WebSocketNegotiationState.Data; } else { List<byte> LeftoverBytes = new List<byte>(); while (i < numberOfBytes) LeftoverBytes.Add(data[i++]); _QueuedBytes = LeftoverBytes.ToArray(); } break; case WebSocketNegotiationState.Data: byte UnMaskedByte = (byte)(data[i] ^ _FrameMask[_FramePayloadReceived++ % 4]); // Check if the byte needs to be UTF-8 decoded if (UnMaskedByte < 128) { AddToInputQueue(UnMaskedByte); } else if ((UnMaskedByte > 191) && (UnMaskedByte < 224)) { // Handle UTF-8 decode if (i < (numberOfBytes - 1)) { byte UnMaskedByte2 = (byte)(data[++i] ^ _FrameMask[_FramePayloadReceived++ % 4]); AddToInputQueue((byte)(((UnMaskedByte & 31) << 6) | (UnMaskedByte2 & 63))); } else { _QueuedBytes = new byte[] { data[i] }; } } else { // Handle UTF-8 decode (should never need this, but included anyway) if (i < (numberOfBytes - 2)) { byte UnMaskedByte2 = (byte)(data[++i] ^ _FrameMask[_FramePayloadReceived++ % 4]); byte UnMaskedByte3 = (byte)(data[++i] ^ _FrameMask[_FramePayloadReceived++ % 4]); AddToInputQueue((byte)(((UnMaskedByte & 15) << 12) | ((UnMaskedByte2 & 63) << 6) | (UnMaskedByte3 & 63))); } else if (i < (numberOfBytes - 1)) { _QueuedBytes = new byte[] { data[i], data[++i] }; } else { _QueuedBytes = new byte[] { data[i] }; } } // Check if we've received the full payload if (_FramePayloadReceived == _FramePayloadLength) _State = WebSocketNegotiationState.NeedPacketStart; break; } } }
protected void NegotiateInboundRFC6455(byte[] data, int numberOfBytes) { if (_QueuedBytes != null) { MemoryStream MS = new MemoryStream(); MS.Write(_QueuedBytes, 0, _QueuedBytes.Length); MS.Write(data, 0, data.Length); data = MS.ToArray(); numberOfBytes = data.Length; _QueuedBytes = null; } for (int i = 0; i < numberOfBytes; i++) { // Check what the client packet state is switch (_State) { case WebSocketNegotiationState.NeedPacketStart: // Next byte will give us the opcode, and also tell is if the message is fragmented _FrameMask = new byte[4]; _FrameOpCode = data[i]; _FramePayloadLength = 0; _FramePayloadReceived = 0; _State = WebSocketNegotiationState.NeedPayloadLength; break; case WebSocketNegotiationState.NeedPayloadLength: _FramePayloadLength = (data[i] & 0x7F); if (_FramePayloadLength <= 125) { _State = WebSocketNegotiationState.NeedMaskingKey; } else if (_FramePayloadLength == 126) { if (i < (numberOfBytes - 2)) { byte[] Bytes = new byte[] { data[++i], data[++i] }; _FramePayloadLength = BitConverter.ToInt16(Bytes, 0); _State = WebSocketNegotiationState.NeedMaskingKey; } else { List <byte> LeftoverBytes = new List <byte>(); while (i < numberOfBytes) { LeftoverBytes.Add(data[i++]); } _QueuedBytes = LeftoverBytes.ToArray(); } } else if (_FramePayloadLength == 127) { if (i < (numberOfBytes - 8)) { byte[] Bytes = new byte[] { data[++i], data[++i], data[++i], data[++i], data[++i], data[++i], data[++i], data[++i] }; _FramePayloadLength = BitConverter.ToInt64(Bytes, 0); _State = WebSocketNegotiationState.NeedMaskingKey; } else { List <byte> LeftoverBytes = new List <byte>(); while (i < numberOfBytes) { LeftoverBytes.Add(data[i++]); } _QueuedBytes = LeftoverBytes.ToArray(); } } break; case WebSocketNegotiationState.NeedMaskingKey: if (i < (numberOfBytes - 3)) { byte[] Bytes = new byte[] { data[i], data[++i], data[++i], data[++i] }; int TempMask = BitConverter.ToInt32(Bytes, 0); _FrameMask[3] = (byte)((TempMask & 0xFF000000) >> 24); _FrameMask[2] = (byte)((TempMask & 0x00FF0000) >> 16); _FrameMask[1] = (byte)((TempMask & 0x0000FF00) >> 8); _FrameMask[0] = (byte)(TempMask & 0x000000FF); _State = WebSocketNegotiationState.Data; } else { List <byte> LeftoverBytes = new List <byte>(); while (i < numberOfBytes) { LeftoverBytes.Add(data[i++]); } _QueuedBytes = LeftoverBytes.ToArray(); } break; case WebSocketNegotiationState.Data: byte UnMaskedByte = (byte)(data[i] ^ _FrameMask[_FramePayloadReceived++ % 4]); // Check if the byte needs to be UTF-8 decoded if (UnMaskedByte < 128) { AddToInputQueue(UnMaskedByte); } else if ((UnMaskedByte > 191) && (UnMaskedByte < 224)) { // Handle UTF-8 decode if (i < (numberOfBytes - 1)) { byte UnMaskedByte2 = (byte)(data[++i] ^ _FrameMask[_FramePayloadReceived++ % 4]); AddToInputQueue((byte)(((UnMaskedByte & 31) << 6) | (UnMaskedByte2 & 63))); } else { _QueuedBytes = new byte[] { data[i] }; } } else { // Handle UTF-8 decode (should never need this, but included anyway) if (i < (numberOfBytes - 2)) { byte UnMaskedByte2 = (byte)(data[++i] ^ _FrameMask[_FramePayloadReceived++ % 4]); byte UnMaskedByte3 = (byte)(data[++i] ^ _FrameMask[_FramePayloadReceived++ % 4]); AddToInputQueue((byte)(((UnMaskedByte & 15) << 12) | ((UnMaskedByte2 & 63) << 6) | (UnMaskedByte3 & 63))); } else if (i < (numberOfBytes - 1)) { _QueuedBytes = new byte[] { data[i], data[++i] }; } else { _QueuedBytes = new byte[] { data[i] }; } } // Check if we've received the full payload if (_FramePayloadReceived == _FramePayloadLength) { _State = WebSocketNegotiationState.NeedPacketStart; } break; } } }
protected void NegotiateInboundHixie76(byte[] data, int numberOfBytes) { if (_QueuedBytes != null) { MemoryStream MS = new MemoryStream(); MS.Write(_QueuedBytes, 0, _QueuedBytes.Length); MS.Write(data, 0, data.Length); data = MS.ToArray(); numberOfBytes = data.Length; _QueuedBytes = null; } for (int i = 0; i < numberOfBytes; i++) { // Check what the client packet state is switch (_State) { case WebSocketNegotiationState.NeedPacketStart: // Check for 0x00 to indicate the start of a data packet if (data[i] == 0x00) { _State = WebSocketNegotiationState.Data; } break; case WebSocketNegotiationState.Data: // We're in a data packet, so check for 0xFF, which indicates the data packet is done if (data[i] == 0xFF) { _State = WebSocketNegotiationState.NeedPacketStart; } else { // Check if the byte needs to be UTF-8 decoded if (data[i] < 128) { AddToInputQueue(data[i]); } else if ((data[i] > 191) && (data[i] < 224)) { // Handle UTF-8 decode if (i < (numberOfBytes - 1)) { AddToInputQueue((byte)(((data[i] & 31) << 6) | (data[++i] & 63))); } else { _QueuedBytes = new byte[] { data[i] }; } } else { // Handle UTF-8 decode (should never need this, but included anyway) if (i < (numberOfBytes - 2)) { AddToInputQueue((byte)(((data[i] & 15) << 12) | ((data[++i] & 63) << 6) | (data[++i] & 63))); } else if (i < (numberOfBytes - 1)) { _QueuedBytes = new byte[] { data[i], data[++i] }; } else { _QueuedBytes = new byte[] { data[i] }; } } } break; } } }