Exemplo n.º 1
0
        internal WebSocket(TcpSocket socket, HttpServerRequest context, ArraySegment <byte> head)
        {
            _context                = context;
            _socket                 = socket;
            _socket.OnData         += OnData;
            _socket.OnDisconnected += OnSocketDisconnected;
            _recvstate              = RecvStat.Start1;
            _fragmented             = 0;
            _payloadData            = new BufferData();
            _sendingQueue           = new BufferData();
            _sendingTextMode        = false;
            _sendingMaskMode        = false;
            _isserver               = true;
            _state = SocketStat.Open;

            if (head.Count > 0)
            {
                OnData(_socket, head);
            }

            _socket.NoDelay = true;
            _socket.ReceiveStart();
        }
Exemplo n.º 2
0
        private void OnData(TcpSocket socket, ArraySegment <byte> data)
        {
            var buf   = data.Array;
            var start = data.Offset;
            var end   = data.Offset + data.Count;
            var p     = start;

            while (p < end)
            {
                switch (_recvstate)
                {
                case RecvStat.Start1: {
                    byte tmp = buf[p];
                    if ((tmp & 0x70) != 0)
                    {
                        Error("RSV1, RSV2 and RSV3 must be clear", 1002);
                    }
                    _fin    = (tmp & 0x80) == 0x80;
                    _opcode = (byte)(tmp & 0x0f);
                    if (_opcode == 0)
                    {
                        if (_fragmented == 0)
                        {
                            Error("invalid opcode: " + _opcode, 1002);
                            return;
                        }
                        else
                        {
                            _opcode = _fragmented;
                        }
                    }
                    else if (_opcode == 0x01 || _opcode == 0x02)
                    {
                        if (_fragmented != 0)
                        {
                            Error("invalid opcode: " + _opcode, 1002);
                            return;
                        }
                    }
                    else if (_opcode > 0x07 && _opcode < 0x0b)
                    {
                        if (!_fin)
                        {
                            Error("FIN must be set", 1002);
                            return;
                        }
                    }
                    else
                    {
                        Error("invalid opcode: " + _opcode, 1002);
                        return;
                    }

                    p++;
                    _recvstate = RecvStat.PayloadLength1;
                    break;
                }

                case RecvStat.PayloadLength1: {
                    _payloadLength = (long)(buf[p] & 0x7f);
                    _masked        = (buf[p] & 0x80) == 0x80;
                    _maskValue     = 0;
                    _maskPos       = 0;

                    if (_payloadLength == 126)
                    {
                        _payloadLength = 0;
                        _index         = 2;
                        _recvstate     = RecvStat.PayloadLength2;
                    }
                    else if (_payloadLength == 127)
                    {
                        _payloadLength = 0;
                        _index         = 8;
                        _recvstate     = RecvStat.PayloadLength2;
                    }
                    else
                    {
                        _recvstate = _masked ? RecvStat.Mask : RecvStat.Data;
                        _index     = 4;
                    }

                    p++;
                    break;
                }

                case RecvStat.PayloadLength2: {
                    while (_index > 0 && p < end)
                    {
                        _index--;
                        _payloadLength |= ((long)buf[p] << (8 * _index));
                        p++;
                    }
                    if (_index == 0)
                    {
                        _recvstate = _masked ? RecvStat.Mask : RecvStat.Data;
                        _index     = 4;
                    }
                    break;
                }

                case RecvStat.Mask: {
                    while (_index > 0 && p < end)
                    {
                        _index--;
                        _maskValue |= ((uint)buf[p] << (8 * (3 - _index)));
                        p++;
                    }
                    if (_index == 0)
                    {
                        _recvstate = RecvStat.Data;
                    }
                    break;
                }

                case RecvStat.Data: {
                    var len = (int)Math.Min(_payloadLength, end - p);
                    if (_masked)
                    {
                        for (var i = p; i < p + len; i++)
                        {
                            buf[i] ^= (byte)(_maskValue >> (8 * (_maskPos & 3)));
                            _maskPos++;
                        }
                    }
                    _payloadData.Add(buf, p, len);
                    _payloadLength -= len;
                    p += len;
                    if (_payloadLength == 0)
                    {
                        _recvstate = RecvStat.Start1;
                        OnFrameReceived();
                    }
                    break;
                }
                }
            }

            if (_recvstate == RecvStat.Data && _payloadLength == 0)
            {
                _recvstate = RecvStat.Start1;
                OnFrameReceived();
            }
        }