private void ReceiveData(List <byte> data, IReadState readState, Action <FrameType, byte[]> processFrame) { while (data.Count >= 2) { bool isFinal = (data[0] & 128) != 0; var frameType = (FrameType)(data[0] & 15); int length = (data[1] & 127); int 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 } if (data.Count < index + payloadLength) { return; //Not complete } IEnumerable <byte> payload = data .Skip(index) .Take(payloadLength) .Select(b => b); readState.Data.AddRange(payload); data.RemoveRange(0, index + payloadLength); if (frameType != FrameType.Continuation) { readState.FrameType = frameType; } if (!isFinal || !readState.FrameType.HasValue) { continue; } byte[] stateData = readState.Data.ToArray(); FrameType?stateFrameType = readState.FrameType; readState.Clear(); processFrame(stateFrameType.Value, stateData); } }
private ConnectionCloseFrame(Error error, FrameType?errorFrameType, ReasonPhrase reasonPhrase) { Error = error; ErrorFrameType = errorFrameType; ReasonPhrase = reasonPhrase; }
public Hybi13Handler(WebSocketHttpRequest request, IWebSocketConnection connection) { _request = request; _connection = connection; _data = ArrayPool <byte> .Shared.Rent(1 * 1024 * 1024); // 1 MB read buffer _dataLen = 0; _frameType = null; _message = ArrayPool <byte> .Shared.Rent(1 * 1024 * 1024); // 1 MB message length _messageLen = 0; }
public Frame(FrameType?type) { Type = type; }
public void Clear() { Data.Clear(); FrameType = null; }
public void Clear() { _data.Clear(); _frameType = null; }
/// <summary> /// Clears the current state. /// </summary> public void Clear() { this.Data.Clear(); this.FrameType = null; }
private void Clear() { _frameType = null; _messageLen = 0; }
private void ReceiveData() { while (_dataLen >= 2) { FleckLog.Debug("Trying to read a packet"); 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 || !frameType.IsDefined() || reservedBits != 0 || // Must be zero per spec 5.2 (frameType == FrameType.Continuation && !_frameType.HasValue)) { throw new WebSocketException(WebSocketStatusCodes.ProtocolError); } var index = 2; int payloadLength; if (length == 127) { if (_dataLen < index + 8) { return; //Not complete } payloadLength = new Span <byte>(_data, index, 8).ToLittleEndianInt(); index += 8; } else if (length == 126) { if (_dataLen < index + 2) { return; //Not complete } payloadLength = new Span <byte>(_data, index, 2).ToLittleEndianInt(); index += 2; } else { payloadLength = length; } FleckLog.Debug($"Expecting {payloadLength} byte payload"); if (_dataLen < index + 4) { return; //Not complete } var maskBytes = new Span <byte>(_data, index, 4); index += 4; if (_dataLen < index + payloadLength) { return; //Not complete } var payloadData = new Span <byte>(_data, index, payloadLength); for (var i = 0; i < payloadLength; i++) { payloadData[i] = (byte)(payloadData[i] ^ maskBytes[i % 4]); } if (_messageLen + payloadLength > _message.Length) { throw new WebSocketException(WebSocketStatusCodes.MessageTooBig); } var messageDest = new Span <byte>(_message, _messageLen, payloadLength); payloadData.CopyTo(messageDest); _messageLen += payloadLength; var bytesUsed = index + payloadLength; Buffer.BlockCopy(_data, bytesUsed, _data, 0, _dataLen - bytesUsed); _dataLen -= index + payloadLength; if (frameType != FrameType.Continuation) { _frameType = frameType; } if (isFinal && _frameType.HasValue) { FleckLog.Debug($"Frame finished: {_frameType.Value}, {_messageLen} bytes"); ProcessFrame(_frameType.Value, new ArraySegment <byte>(_message, 0, _messageLen)); Clear(); } } }
public void Clear() { Data.Clear(); FrameType = null; FragmentNumber = 1; }
public static AshFrame CreateFromInput(int[] buffer) { // A frame must be at least 3 bytes long if (buffer.Length < 3) { return(null); } // Remove byte stuffing int[] unstuffedData = new int[buffer.Length]; int outLength = 0; bool escape = false; int d = 0; foreach (int data in buffer) { d = data; if (escape) { escape = false; if ((d & 0x20) == 0) { d = (byte)(d + 0x20); } else { d = (byte)(d & 0xDF); } } else if (d == 0x7D) { escape = true; continue; } unstuffedData[outLength++] = d; } // Check CRC if (CheckCRC(unstuffedData, outLength) != 0) { return(null); } FrameType?frameType = GetFrameType(unstuffedData); if (frameType == null) { Log.Debug("Invalid ASH frame type {Type}", unstuffedData[0].ToString("X2")); return(null); } int[] frameBuffer = new int[outLength]; Array.Copy(unstuffedData, 0, frameBuffer, 0, outLength); switch (frameType) { case FrameType.ACK: return(new AshFrameAck(frameBuffer)); case FrameType.DATA: DataRandomise(frameBuffer, 1, frameBuffer.Length); return(new AshFrameData(frameBuffer)); case FrameType.ERROR: return(new AshFrameError(frameBuffer)); case FrameType.NAK: return(new AshFrameNak(unstuffedData)); case FrameType.RST: return(new AshFrameRst()); case FrameType.RSTACK: return(new AshFrameRstAck(frameBuffer)); default: break; } return(null); }