public WebSocketFrameBuilder() { _logger = LogManager.GetLogger(typeof(WebSocketFrameBuilder)); lock (_syncFrameBuilderState) { _frameBuilderState = FrmeBuilderState.GET_INFO; } }
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; } }
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; } }
private void HaveLength() { if (_opCode < 0x08 && MaxPayloadExceeded(_payLoadLength)) { return; } lock (_syncFrameBuilderState) { if (_isMaskBitSet) { _frameBuilderState = FrmeBuilderState.GET_MASK; } else { _frameBuilderState = FrmeBuilderState.GET_DATA; } } }
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; } }
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; } }
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(); } }
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(); } }