Beispiel #1
0
        public static void ReceiveData(List <byte> data, ReadState readState, Fleck2Extensions.Action <FrameType, byte[]> processFrame)
        {
            while (data.Count >= 2)
            {
                var isFinal      = (data[0] & 128) != 0;
                var reservedBits = (data[0] & 112);
                var frameType    = (FrameType)(data[0] & 15);
                var isMasked     = (data[1] & 128) != 0;
                var length       = (data[1] & 127);


                if (!isMasked ||
                    !Enum.IsDefined(typeof(FrameType), frameType) ||
                    reservedBits != 0 || //Must be zero per spec 5.2
                    (frameType == FrameType.Continuation && !readState.FrameType.HasValue))
                {
                    throw new WebSocketException(WebSocketStatusCodes.ProtocolError);
                }

                var index = 2;
                int payloadLength;

                switch (length)
                {
                case 127:
                    if (data.Count < index + 8)
                    {
                        return;     //Not complete
                    }
                    payloadLength = data.Skip(index).Take(8).ToArray().ToLittleEndianInt();
                    index        += 8;
                    break;

                case 126:
                    if (data.Count < index + 2)
                    {
                        return;     //Not complete
                    }
                    payloadLength = data.Skip(index).Take(2).ToArray().ToLittleEndianInt();
                    index        += 2;
                    break;

                default:
                    payloadLength = length;
                    break;
                }

                if (data.Count < index + 4)
                {
                    return; //Not complete
                }
                var maskBytes = data.Skip(index).Take(4).ToList();

                index += 4;

                if (data.Count < index + payloadLength)
                {
                    return; //Not complete
                }
                var i       = 0;
                var payload = data.Skip(index)
                              .Take(payloadLength)
                              .Select(value => (byte)(value ^ maskBytes[i++ % 4]));

                readState.Data.AddRange(payload);
                data.RemoveRange(0, index + payloadLength);

                if (frameType != FrameType.Continuation)
                {
                    readState.FrameType = frameType;
                }

                if (!isFinal || !readState.FrameType.HasValue)
                {
                    continue;
                }

                var stateData      = readState.Data.ToArray();
                var stateFrameType = readState.FrameType;
                readState.Clear();

                processFrame(stateFrameType.Value, stateData);
            }
        }
Beispiel #2
0
        public static void ReceiveData(List<byte> data, ReadState readState, Action<FrameType, byte[]> processFrame)
        {
            while (data.Count >= 2)
            {
                var isFinal = (data[0] & 128) != 0;
                var frameType = (FrameType)(data[0] & 15);
                var isMasked = (data[1] & 128) != 0;
                var length = (data[1] & 127);

                if (!isMasked)
                    throw new WebSocketException("Client data must be masked");

                if (frameType == FrameType.Continuation && !readState.FrameType.HasValue)
                    throw new WebSocketException("Unexpected continuation frame received");

                var index = 2;
                int payloadLength;

                if (length == 127)
                {
                    if (data.Count < index + 8)
                        return; //Not complete
                    payloadLength = data.Skip(index).Take(8).ToArray().ToLittleEndianInt();
                    index += 8;
                }
                else if (length == 126)
                {
                    if (data.Count < index + 2)
                        return; //Not complete
                    payloadLength = data.Skip(index).Take(2).ToArray().ToLittleEndianInt();
                    index += 2;
                }
                else
                {
                    payloadLength = length;
                }

                if (data.Count < index + 4)
                    return; //Not complete

                var maskBytes = data.Skip(index).Take(4).ToArray();

                index += 4;

                if (data.Count < index + payloadLength)
                    return; //Not complete

                var payload = data
                                .Skip(index)
                                .Take(payloadLength)
                                .Select((x, i) => (byte)(x ^ maskBytes[i % 4]));

                readState.Data.AddRange(payload);
                data.RemoveRange(0, index + payloadLength);

                if (frameType != FrameType.Continuation)
                    readState.FrameType = frameType;

                if (isFinal && readState.FrameType.HasValue)
                {
                    var stateData = readState.Data.ToArray();
                    var stateFrameType = readState.FrameType;
                    readState.Clear();

                    processFrame(stateFrameType.Value, stateData);
                }
            }
        }
Beispiel #3
0
        public static void ReceiveData(List<byte> data, ReadState readState, Fleck2Extensions.Action<FrameType, byte[]> processFrame)
        {
            while (data.Count >= 2)
            {
                var isFinal = (data[0] & 128) != 0;
                var reservedBits = (data[0] & 112);
                var frameType = (FrameType)(data[0] & 15);
                var isMasked = (data[1] & 128) != 0;
                var length = (data[1] & 127);

                if (!isMasked
                    || !Enum.IsDefined(typeof(FrameType), frameType)
                    || reservedBits != 0 //Must be zero per spec 5.2
                    || (frameType == FrameType.Continuation && !readState.FrameType.HasValue))
                    throw new WebSocketException(WebSocketStatusCodes.ProtocolError);

                var index = 2;
                int payloadLength;

                switch (length)
                {
                    case 127:
                        if (data.Count < index + 8)
                            return; //Not complete
                        payloadLength = data.Skip(index).Take(8).ToArray().ToLittleEndianInt();
                        index += 8;
                        break;
                    case 126:
                        if (data.Count < index + 2)
                            return; //Not complete
                        payloadLength = data.Skip(index).Take(2).ToArray().ToLittleEndianInt();
                        index += 2;
                        break;
                    default:
                        payloadLength = length;
                        break;
                }

                if (data.Count < index + 4)
                    return; //Not complete

                var maskBytes = data.Skip(index).Take(4).ToList();

                index += 4;

                if (data.Count < index + payloadLength)
                    return; //Not complete

                var i = 0;
                var payload = data.Skip(index)
                              .Take(payloadLength)
                              .Select(value => (byte)(value ^ maskBytes[i++ % 4]));

                readState.Data.AddRange(payload);
                data.RemoveRange(0, index + payloadLength);

                if (frameType != FrameType.Continuation)
                    readState.FrameType = frameType;

                if (!isFinal || !readState.FrameType.HasValue)
                {
                    continue;
                }

                var stateData = readState.Data.ToArray();
                var stateFrameType = readState.FrameType;
                readState.Clear();

                processFrame(stateFrameType.Value, stateData);
            }
        }
Beispiel #4
0
        public static void ReceiveData(List <byte> data, ReadState readState, Action <FrameType, byte[]> processFrame)
        {
            while (data.Count >= 2)
            {
                var isFinal      = (data[0] & 128) != 0;
                var reservedBits = (data[0] & 112);
                var frameType    = (FrameType)(data[0] & 15);
                var isMasked     = (data[1] & 128) != 0;
                var length       = (data[1] & 127);


                if (!isMasked ||
                    !Enum.IsDefined(typeof(FrameType), frameType) ||
                    reservedBits != 0 ||             //Must be zero per spec 5.2
                    (frameType == FrameType.Continuation && !readState.FrameType.HasValue))
                {
                    throw new WebSocketException(WebSocketStatusCodes.ProtocolError);
                }

                var index = 2;
                int payloadLength;

                if (length == 127)
                {
                    if (data.Count < index + 8)
                    {
                        return;                         //Not complete
                    }
                    //payloadLength = data.Skip(index).Take(8).ToArray().ToLittleEndianInt();
                    var _data = LinqExtensions.SkipTakeToArray(
                        data.ToArray(),
                        index,
                        8
                        );
                    payloadLength = IntExtensions.ToLittleEndianInt(_data);

                    index += 8;
                }
                else if (length == 126)
                {
                    if (data.Count < index + 2)
                    {
                        return;                         //Not complete
                    }
                    //payloadLength = data.Skip(index).Take(2).ToArray().ToLittleEndianInt();
                    var _data = LinqExtensions.SkipTakeToArray(
                        data.ToArray(),
                        index,
                        2
                        );
                    payloadLength = IntExtensions.ToLittleEndianInt(_data);

                    index += 2;
                }
                else
                {
                    payloadLength = length;
                }

                if (data.Count < index + 4)
                {
                    return;                     //Not complete
                }
                //var maskBytes = data.Skip(index).Take(4).ToArray();
                var maskBytes = LinqExtensions.SkipTakeToArray(
                    data.ToArray(),
                    index,
                    4
                    );

                index += 4;


                if (data.Count < index + payloadLength)
                {
                    return;                     //Not complete
                }
                //var payload = data
                //.Skip(index)
                //.Take(payloadLength)
                //.Select((x, idx) => (byte)(x ^ maskBytes[idx % 4]));

                var payload = LinqExtensions.SkipTakeToArray(
                    data.ToArray(),
                    index,
                    payloadLength,
                    (x, idx) => (byte)(x ^ maskBytes[idx % 4])
                    );

                readState.Data.AddRange(payload);
                data.RemoveRange(0, index + payloadLength);

                if (frameType != FrameType.Continuation)
                {
                    readState.FrameType = frameType;
                }

                if (isFinal && readState.FrameType.HasValue)
                {
                    var stateData      = readState.Data.ToArray();
                    var stateFrameType = readState.FrameType;
                    readState.Clear();

                    processFrame(stateFrameType.Value, stateData);
                }
            }
        }
Beispiel #5
0
        public static void ReceiveData(List <byte> data, ReadState readState, Action <FrameType, byte[]> processFrame)
        {
            while (data.Count >= 2)
            {
                var isFinal   = (data[0] & 128) != 0;
                var frameType = (FrameType)(data[0] & 15);
                var isMasked  = (data[1] & 128) != 0;
                var length    = (data[1] & 127);

                if (!isMasked)
                {
                    throw new WebSocketException("Client data must be masked");
                }

                if (frameType == FrameType.Continuation && !readState.FrameType.HasValue)
                {
                    throw new WebSocketException("Unexpected continuation frame received");
                }

                var index = 2;
                int payloadLength;

                if (length == 127)
                {
                    if (data.Count < index + 8)
                    {
                        return; //Not complete
                    }
                    payloadLength = data.Skip(index).Take(8).ToArray().ToLittleEndianInt();
                    index        += 8;
                }
                else if (length == 126)
                {
                    if (data.Count < index + 2)
                    {
                        return; //Not complete
                    }
                    payloadLength = data.Skip(index).Take(2).ToArray().ToLittleEndianInt();
                    index        += 2;
                }
                else
                {
                    payloadLength = length;
                }

                if (data.Count < index + 4)
                {
                    return; //Not complete
                }
                var maskBytes = data.Skip(index).Take(4).ToArray();

                index += 4;


                if (data.Count < index + payloadLength)
                {
                    return; //Not complete
                }
                var payload = data
                              .Skip(index)
                              .Take(payloadLength)
                              .Select((x, i) => (byte)(x ^ maskBytes[i % 4]));


                readState.Data.AddRange(payload);
                data.RemoveRange(0, index + payloadLength);

                if (frameType != FrameType.Continuation)
                {
                    readState.FrameType = frameType;
                }

                if (isFinal && readState.FrameType.HasValue)
                {
                    var stateData      = readState.Data.ToArray();
                    var stateFrameType = readState.FrameType;
                    readState.Clear();

                    processFrame(stateFrameType.Value, stateData);
                }
            }
        }
Beispiel #6
0
        private void ProcessData(ArraySegment <byte> data, Action <IList <byte>, FrameType> processFrame)
        {
            var buffer = new byte[data.Count];

            Array.Copy(data.Array, buffer, data.Count);
            readState.Data.AddRange(buffer);

            while (readState.Data.Count() > 2)
            {
                var bytesRead = readState.Data.Count;

                var  reservedBits = (readState.Data[0] & 112);
                bool isFinal      = (readState.Data[0] & 128) != 0;
                //bool isMasked = (readState.Data[1] & 128) != 0;
                var frameType = (FrameType)(readState.Data[0] & 15);

                if (reservedBits != 0)
                {
                    return;
                }


                int length = (readState.Data[1] & 127);
                int index  = 2;
                switch (length)
                {
                case 127:
                    if (bytesRead < index + 8)
                    {
                        return;
                    }
                    readState.Length = readState.Data.Skip(index).Take(8).ToArray().ToLittleEndianInt();
                    index           += 8;
                    break;

                case 126:
                    if (bytesRead < index + 2)
                    {
                        return;
                    }
                    readState.Length = readState.Data.Skip(index).Take(2).ToArray().ToLittleEndianInt();
                    index           += 2;
                    break;

                default:
                    readState.Length = length;
                    break;
                }

                if (readState.Data.Count < index + 4)
                {
                    return;
                }

                if (bytesRead < readState.Length + index)
                {
                    return;
                }

                var payload = readState.Data.GetRange(index, readState.Length);

                readState.Data.RemoveRange(0, index + readState.Length);

                readState.FrameBytes.AddRange(payload);

                if (frameType != FrameType.Continuation)
                {
                    readState.FrameType = frameType;
                }

                if (!isFinal && readState.FrameType.HasValue)
                {
                    continue;
                }

                if (!readState.FrameType.HasValue)
                {
                    throw new Exception("FrameType unknown");
                }
                processFrame(readState.FrameBytes, readState.FrameType.Value);

                readState.Clear();
            }
        }
Beispiel #7
0
        public static void ReceiveData(List<byte> data, ReadState readState, Action<FrameType, byte[]> processFrame)
        {
            while (data.Count >= 2)
            {
                var isFinal = (data[0] & 128) != 0;
                var reservedBits = (data[0] & 112);
                var frameType = (FrameType)(data[0] & 15);
                var isMasked = (data[1] & 128) != 0;
                var length = (data[1] & 127);
                var isControlFrame = (data[0]&15) >= 0x08 && (data[0]&15) <= 0x0F;

                if (!isMasked
                    || !Enum.IsDefined(typeof(FrameType), frameType)
                    || reservedBits != 0 //Must be zero per spec 5.2
                    || (frameType == FrameType.Continuation && !readState.FrameType.HasValue))
                    throw new WebSocketException(WebSocketStatusCodes.ProtocolError);

                var index = 2;
                int payloadLength;

                // control frame types may only have a maximum payload length of 125 (autobahn test case 2.5)
                if (isControlFrame && length > 125)
                    throw new WebSocketException(WebSocketStatusCodes.ProtocolError);

                // control frames must not be fragmented (autobahn test case 5.1)
                if (isControlFrame && !isFinal)
                    throw new WebSocketException(WebSocketStatusCodes.ProtocolError);

                // a close frame MAY contain data, but if it does, it must be at least 2 bytes (autobahn test case 7.3.2)
                if (frameType == FrameType.Close && length == 1)
                    throw new WebSocketException(WebSocketStatusCodes.ProtocolError);

                if (length == 127)
                {
                    if (data.Count < index + 8)
                        return; //Not complete
                    payloadLength = data.Skip(index).Take(8).ToArray().ToLittleEndianInt();
                    index += 8;
                }
                else if (length == 126)
                {
                    if (data.Count < index + 2)
                        return; //Not complete
                    payloadLength = data.Skip(index).Take(2).ToArray().ToLittleEndianInt();
                    index += 2;
                }
                else
                {
                    payloadLength = length;
                }

                if (data.Count < index + 4)
                    return; //Not complete

                var maskBytes = data.Skip(index).Take(4).ToArray();

                index += 4;

                if (data.Count < index + payloadLength)
                    return; //Not complete

                var payload = data
                                .Skip(index)
                                .Take(payloadLength)
                                .Select((x, i) => (byte)(x ^ maskBytes[i % 4]));

                // control frames are processed immediatly (since they cannot be fragmented) and can be receive in between
                // and can be received and processed between a fragmented frame (autobahn test case 5.6)
                if (isControlFrame)
                {
                    processFrame(frameType, payload.ToArray());
                    data.RemoveRange(0, index + payloadLength);
                }
                else
                {
                    readState.Data.AddRange(payload);
                    data.RemoveRange(0, index + payloadLength);

                    // frame types for multiple fragments are sent on the first frame, and the rest of the fragments must
                    // have a frame type of continuation (autobahn test case 5.18)
                    if (readState.FragmentNumber == 1)
                        readState.FrameType = frameType;
                    else if(frameType != FrameType.Continuation)
                        throw new WebSocketException(WebSocketStatusCodes.ProtocolError);

                    readState.FragmentNumber++;

                    if (isFinal && readState.FrameType.HasValue)
                    {
                        var stateData = readState.Data.ToArray();
                        var stateFrameType = readState.FrameType;
                        readState.Clear();

                        processFrame(stateFrameType.Value, stateData);
                    }
                }
            }
        }
Beispiel #8
0
        private static void ReceiveData(List <byte> data, ReadState readState, Action <FrameType, byte[]> processFrame)
        {
            while (data.Count >= 2)
            {
                var isFinal      = (data[0] & 128) != 0;
                var reservedBits = (data[0] & 112);
                var frameType    = (FrameType)(data[0] & 15);
                var isMasked     = (data[1] & 128) != 0;
                var length       = (data[1] & 127);


                if (!isMasked ||
                    !Enum.IsDefined(typeof(FrameType), frameType) ||
                    reservedBits != 0 || //Must be zero per spec 5.2
                    (frameType == FrameType.Continuation && !readState.FrameType.HasValue))
                {
                    throw new WebSocketException(WebSocketStatusCodes.ProtocolError);
                }

                var index = 2;
                int payloadLength;

                if (length == 127)
                {
                    if (data.Count < index + 8)
                    {
                        return; //Not complete
                    }
                    payloadLength = data.Skip(index).Take(8).ToArray().ToLittleEndianInt();
                    index        += 8;
                }
                else if (length == 126)
                {
                    if (data.Count < index + 2)
                    {
                        return; //Not complete
                    }
                    payloadLength = data.Skip(index).Take(2).ToArray().ToLittleEndianInt();
                    index        += 2;
                }
                else
                {
                    payloadLength = length;
                }

                if (data.Count < index + 4)
                {
                    return; //Not complete
                }

                var maskBytes = data.Skip(index).Take(4).ToArray();

                index += 4;


                if (data.Count < index + payloadLength)
                {
                    return; //Not complete
                }

                byte[] payloadData = new byte[payloadLength];
                for (int i = 0; i < payloadLength; i++)
                {
                    payloadData[i] = (byte)(data[index + i] ^ maskBytes[i % 4]);
                }

                readState.Data.AddRange(payloadData);
                data.RemoveRange(0, index + payloadLength);

                if (frameType != FrameType.Continuation)
                {
                    readState.FrameType = frameType;
                }

                if (isFinal && readState.FrameType.HasValue)
                {
                    var stateData      = readState.Data.ToArray();
                    var stateFrameType = readState.FrameType;
                    readState.Clear();

                    processFrame(stateFrameType.Value, stateData);
                }
            }
        }