示例#1
0
 public WebSocketFrameBuilder()
 {
     _logger = LogManager.GetLogger(typeof(WebSocketFrameBuilder));
     lock (_syncFrameBuilderState)
     {
         _frameBuilderState = FrmeBuilderState.GET_INFO;
     }
 }
示例#2
0
 private void Decompress(byte[] msgbuf)
 {
     //do nothing for now...compression not allowed
     _logger.Warn("Frame received as compressed data");
     lock (_syncFrameBuilderState)
     {
         _frameBuilderState = FrmeBuilderState.GET_INFO;
     }
 }
示例#3
0
        private void ControlMessage(byte[] data)
        {
            if (_opCode == 0x08)
            {
                ConnectionCloseEventArgs closeEventArgs;

                if (data.Length == 0)
                {
                    closeEventArgs = new ConnectionCloseEventArgs(WebSocketCloseCode.Normal, "Close frame received - zero bytes received");
                }
                else if (data.Length == 1)
                {
                    closeEventArgs = new ConnectionCloseEventArgs(WebSocketCloseCode.ProtocolError, "Invalid payload load");
                }
                else
                {
                    var code = BitConverter.ToUInt16(data, 0);
                    if (!IsValidErrorCode(code))
                    {
                        closeEventArgs = new ConnectionCloseEventArgs(WebSocketCloseCode.ProtocolError, string.Format("invalid status code {0}", code));
                    }
                    else
                    {
                        closeEventArgs = new ConnectionCloseEventArgs((WebSocketCloseCode)code, "Close frame received");
                    }
                }
                _logger.ErrorFormat("Received close code from connection {0} - {1}", ConnectionId, closeEventArgs.Reason);
                if (OnClose != null)
                {
                    OnClose(this, closeEventArgs);
                }
                return;
            }

            if (_opCode == 0x09)
            {
                if (OnPing != null)
                {
                    OnPing(this, new PingEventArgs(data));
                }
                else
                if (OnPong != null)
                {
                    OnPong(this, new PingEventArgs(data));
                }
            }


            lock (_syncFrameBuilderState)
            {
                _frameBuilderState = FrmeBuilderState.GET_INFO;
            }
        }
示例#4
0
        private void HaveLength()
        {
            if (_opCode < 0x08 && MaxPayloadExceeded(_payLoadLength))
            {
                return;
            }

            lock (_syncFrameBuilderState)
            {
                if (_isMaskBitSet)
                {
                    _frameBuilderState = FrmeBuilderState.GET_MASK;
                }
                else
                {
                    _frameBuilderState = FrmeBuilderState.GET_DATA;
                }
            }
        }
示例#5
0
        private void GetMask()
        {
            byte[] msgbuf          = new byte[4];
            int    maskKeyPosition = GetMaskKeyPosition();

            lock (_syncObject)
            {
                if (_messageStream == null || _messageStream.Length < maskKeyPosition + 4)
                {
                    return;
                }
                _messageStream.Position = maskKeyPosition;
                _messageStream.Read(msgbuf, 0, 4);
            }

            _mask = msgbuf;
            lock (_syncFrameBuilderState)
            {
                _frameBuilderState = FrmeBuilderState.GET_DATA;
            }
        }
示例#6
0
        private void DataMessage()
        {
            if (_isFinBitSet)
            {
                int           messageLength = _messageLength;
                List <byte[]> fragments     = new List <byte[]> (_fragmentsStream);

                _totalPayloadLength = 0;
                _messageLength      = 0;
                _fragmented         = false;

                _fragmentsStream = new List <byte[]>();

                byte[] data = GetDataFromFragments(fragments, messageLength);
                if (_opCode == 2)
                {
                    if (_isFinBitSet)
                    {
                        if (_logger.IsDebugEnabled)
                        {
                            _logger.DebugFormat("Received binary frame from connection {0} of length {1}", ConnectionId, data.Length);
                        }
                        if (OnBinaryFrame != null)
                        {
                            OnBinaryFrame(this, new BinaryFrameEventArgs(data));
                        }
                    }
                    else
                    {
                        if (_logger.IsDebugEnabled)
                        {
                            _logger.DebugFormat("Received multi binary frame from connection {0} of length {1} isfinal: {2} ", ConnectionId, data.Length, _isFinBitSet);
                        }
                        if (OnBinaryMultiFrame != null)
                        {
                            OnBinaryMultiFrame(this, new BinaryMultiFrameEventArgs(data, _isFinBitSet));
                        }
                    }
                }
                else
                {
                    String strdata = Encoding.UTF8.GetString(data, 0, data.Length);
                    if (_isFinBitSet)
                    {
                        if (_logger.IsDebugEnabled)
                        {
                            _logger.DebugFormat("Received text frame from connection {0} of length {1}  ", ConnectionId, strdata.Length);
                        }
                        if (OnTextFrame != null)
                        {
                            OnTextFrame(this, new TextFrameEventArgs(strdata));
                        }
                    }
                    else
                    {
                        if (_logger.IsDebugEnabled)
                        {
                            _logger.DebugFormat("Received multi text frame from connection {0} of length {1} isfinal: {2} ", ConnectionId, strdata.Length, _isFinBitSet);
                        }
                        if (OnTextMultiFrame != null)
                        {
                            OnTextMultiFrame(this, new TextMultiFrameEventArgs(strdata, _isFinBitSet));
                        }
                    }
                }
            }

            lock (_syncFrameBuilderState)
            {
                _frameBuilderState = FrmeBuilderState.GET_INFO;
            }
        }
示例#7
0
        private void GetData()
        {
            byte[] msgbuf        = new byte[0];
            int    payLoadLength = (int)_payLoadLength;

            if (payLoadLength > 0)
            {
                msgbuf = new byte[payLoadLength];
                var dataPosition = GetPayLoadDataPosition();
                lock (_syncObject)
                {
                    if (_messageStream == null || _messageStream.Length < payLoadLength + dataPosition)
                    {
                        return;
                    }
                    _messageStream.Position = dataPosition;
                    _messageStream.Read(msgbuf, 0, payLoadLength);

                    // now remove data read from memory stream
                    MemoryStream leftovermessagestream = new MemoryStream();
                    if (_messageStream.Length > payLoadLength + dataPosition)
                    {
                        int    leftoverBytesLength = (int)_messageStream.Length - (payLoadLength + dataPosition);
                        byte[] leftoverbytes       = new byte[leftoverBytesLength];
                        _messageStream.Read(leftoverbytes, 0, leftoverBytesLength);

                        leftovermessagestream.Write(leftoverbytes, 0, leftoverBytesLength);
                    }
                    try
                    {
                        _messageStream.Close();
                    }
                    finally
                    {
                    }
                    _messageStream = leftovermessagestream;
                }

                if (_isMaskBitSet)
                {
                    const int maskKeyLen = 4;
                    // apply the mask key
                    for (int i = 0; i < msgbuf.Length; i++)
                    {
                        msgbuf[i] = (Byte)(msgbuf[i] ^ _mask[i % maskKeyLen]);
                    }
                }
            }

            if (_opCode > 0x07)
            {
                ControlMessage(msgbuf);
            }
            else if (_compressed)
            {
                lock (_syncFrameBuilderState)
                {
                    _frameBuilderState = FrmeBuilderState.INFLATING;
                }
                Decompress(msgbuf);
            }
            else if (PushFragment(msgbuf))
            {
                DataMessage();
            }
        }
示例#8
0
        private void GetInfo()
        {
            byte[] msgbuf = new byte[2];
            lock (_syncObject)
            {
                if (_messageStream == null || _messageStream.Length < 2)
                {
                    return;
                }
                _messageStream.Position = 0;
                _messageStream.Read(msgbuf, 0, 2);
            }


            if ((msgbuf[0] & 0x30) != 0x00)
            {
                RaiseError(new ErrorEventArgs(1002, "RSV2 and RSV3 must be clear"));
                return;
            }

            var compressed = (msgbuf[0] & 0x40) == 0x40;

            if (compressed)
            {
                RaiseError(new ErrorEventArgs(1002, "RSV1 must be clear and compressed data not supported"));
                return;
            }

            // process first byte
            byte finBitFlag = 0x80;
            byte opCodeFlag = 0x0F;

            _isFinBitSet = (msgbuf[0] & finBitFlag) == finBitFlag;
            _opCode      = msgbuf[0] & opCodeFlag;


            //  process second byte
            byte byte2    = msgbuf[1];
            byte maskFlag = 0x80;

            _isMaskBitSet = (byte2 & maskFlag) == maskFlag;

            byte payloadLenFlag = 0x7F;

            _payLoadLength = (uint)(byte2 & payloadLenFlag);


            if (_opCode == 0x00)
            {
                if (compressed)
                {
                    RaiseError(new ErrorEventArgs(1002, "RSV1 must be clear and compressed data not supported"));
                    return;
                }
                if (!_fragmented)
                {
                    RaiseError(new ErrorEventArgs(1002, string.Format("invalid opcode {0}", _opCode)));
                    return;
                }
            }
            else if (_opCode == 0x01 || _opCode == 0x02)
            {
                if (_fragmented)
                {
                    RaiseError(new ErrorEventArgs(1002, string.Format("invalid opcode {0}", _opCode)));
                    return;
                }
                _compressed = compressed;
            }
            else if (_opCode > 0x07 && _opCode < 0x0b)
            {
                if (!_isFinBitSet)
                {
                    RaiseError(new ErrorEventArgs(1002, "FIN must be set"));
                    return;
                }

                if (compressed)
                {
                    RaiseError(new ErrorEventArgs(1002, "RSV1 must be clear"));
                    return;
                }

                if (_payLoadLength > 0x7d)
                {
                    RaiseError(new ErrorEventArgs(1002, "invalid payload length"));
                    return;
                }
            }
            else
            {
                RaiseError(new ErrorEventArgs(1002, string.Format("invalid opcode {0}", _opCode)));
                return;
            }

            if (!_isFinBitSet && !_fragmented)
            {
                _fragmented = true;
            }


            if (_payLoadLength == 126)
            {
                lock (_syncFrameBuilderState)
                {
                    _frameBuilderState = FrmeBuilderState.GET_PAYLOAD_LENGTH_16;
                }
            }
            else if (_payLoadLength == 127)
            {
                lock (_syncFrameBuilderState)
                {
                    _frameBuilderState = FrmeBuilderState.GET_PAYLOAD_LENGTH_64;
                }
            }
            else
            {
                HaveLength();
            }
        }