private WebSocketFrame ReadFrame() { WebSocketFrameHeader frameHeader = ReadFrameHeader(); if (frameHeader.PayloadLength > int.MaxValue) { throw new HcduServerException("Long messages are not supported."); } if (frameHeader.Mask == null) { throw new HcduServerException("Client messages should be masked."); } byte[] content = HttpUtils.ReadBlock(stream, (int)frameHeader.PayloadLength); if (frameHeader.Mask != null) { for (int i = 0; i < content.Length; i++) { content[i] = (byte)(content[i] ^ frameHeader.Mask[i % 4]); } } WebSocketFrame frame = new WebSocketFrame(); frame.Header = frameHeader; frame.Content = content; return(frame); }
private WebSocketFrameHeader ReadFrameHeader() { byte[] primaryHeader = HttpUtils.ReadBlock(stream, 2); WebSocketFrameHeader header = new WebSocketFrameHeader(); header.IsLast = (primaryHeader[0] & 0x80) != 0; header.OpCode = (byte)(primaryHeader[0] & 0x0F); header.PayloadLength = (byte)(primaryHeader[1] & 0x7F); if (header.PayloadLength == 126) { byte[] extLengthHeader = HttpUtils.ReadBlock(stream, 2); header.PayloadLength = BitConverter.ToUInt16(extLengthHeader, 0); } if (header.PayloadLength == 127) { byte[] extLengthHeader = HttpUtils.ReadBlock(stream, 8); header.PayloadLength = BitConverter.ToUInt64(extLengthHeader, 0); } if ((primaryHeader[0] & 0x80) != 0) { header.Mask = HttpUtils.ReadBlock(stream, 4); } return(header); }
private void ListenerLoop() { WebSocketFrameHeader messageHeader = null; MemoryStream messageContent = new MemoryStream(); ulong messageLength = 0; //todo: stop gracefully while (!isClosed) { WebSocketFrame frame = ReadFrame(); if (WebSocketOpcodes.IsControlFrame(frame.Header.OpCode)) { //todo: remove magic number if (!frame.Header.IsLast || frame.Header.PayloadLength > 125) { throw new HcduServerException(string.Format("Invalid control frame (Opcode: {0}, FIN: {1}, Length: {2}).", frame.Header.OpCode, frame.Header.IsLast, frame.Header.PayloadLength)); } HandleControlFrame(frame); } if (messageHeader == null) { if (frame.Header.OpCode == WebSocketOpcodes.ContinuationFrame) { throw new HcduServerException("Continuation frame cannot start message."); } messageHeader = frame.Header; } messageLength += frame.Header.PayloadLength; if (messageLength > int.MaxValue) { throw new HcduServerException("Long messages are not supported."); } messageContent.Write(frame.Content, 0, frame.Content.Length); if (frame.Header.IsLast) { WebSocketMessage message = new WebSocketMessage(); message.OpCode = messageHeader.OpCode; message.Content = messageContent.ToArray(); messageHeader = null; messageContent = new MemoryStream(); HandleMessage(message); } } }
private WebSocketFrameHeader ReadFrameHeader() { byte[] primaryHeader = HttpUtils.ReadBlock(stream, 2); WebSocketFrameHeader header = new WebSocketFrameHeader(); header.IsLast = (primaryHeader[0] & 0x80) != 0; header.OpCode = (byte) (primaryHeader[0] & 0x0F); header.PayloadLength = (byte) (primaryHeader[1] & 0x7F); if (header.PayloadLength == 126) { byte[] extLengthHeader = HttpUtils.ReadBlock(stream, 2); header.PayloadLength = BitConverter.ToUInt16(extLengthHeader, 0); } if (header.PayloadLength == 127) { byte[] extLengthHeader = HttpUtils.ReadBlock(stream, 8); header.PayloadLength = BitConverter.ToUInt64(extLengthHeader, 0); } if ((primaryHeader[0] & 0x80) != 0) { header.Mask = HttpUtils.ReadBlock(stream, 4); } return header; }