private async Task ReadNextFrameAsync(CancellationToken cancellationToken) { await EnsureDataAvailableOrReadAsync(2, cancellationToken); int frameHeaderSize = FrameHeader.CalculateFrameHeaderSize(_receiveBuffer[_receiveBufferOffset + 1]); await EnsureDataAvailableOrReadAsync(frameHeaderSize, cancellationToken); _frameInProgress = new FrameHeader(new ArraySegment <byte>(_receiveBuffer, _receiveBufferOffset, frameHeaderSize)); _receiveBufferOffset += frameHeaderSize; _receiveBufferBytes -= frameHeaderSize; _frameBytesRemaining = _frameInProgress.DataLength; if (_frameInProgress.AreReservedSet()) { await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Unexpected reserved bits set", cancellationToken); } if (_unmaskInput != _frameInProgress.Masked) { await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Incorrect masking", cancellationToken); } if (!ValidateOpCode(_frameInProgress.OpCode)) { await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Invalid opcode: " + _frameInProgress.OpCode, cancellationToken); } if (_frameInProgress.IsControlFrame) { if (_frameBytesRemaining > 125) { await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Invalid control frame size", cancellationToken); } if (!_frameInProgress.Fin) { await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Fragmented control frame", cancellationToken); } if (_frameInProgress.OpCode == Constants.OpCodes.PingFrame || _frameInProgress.OpCode == Constants.OpCodes.PongFrame) { // Drain it, should be less than 125 bytes await EnsureDataAvailableOrReadAsync((int)_frameBytesRemaining, cancellationToken); if (_frameInProgress.OpCode == Constants.OpCodes.PingFrame) { await SendPongReplyAsync(cancellationToken); } _receiveBufferOffset += (int)_frameBytesRemaining; _receiveBufferBytes -= (int)_frameBytesRemaining; _frameBytesRemaining = 0; _frameInProgress = null; } } else if (_firstDataOpCode.HasValue && _frameInProgress.OpCode != Constants.OpCodes.ContinuationFrame) { // A data frame is already in progress, but this new frame is not a continuation frame. await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Expected a continuation frame: " + _frameInProgress.OpCode, cancellationToken); } }
private async Task ReadNextFrameAsync(CancellationToken cancellationToken) { await EnsureDataAvailableOrReadAsync(2, cancellationToken); int frameHeaderSize = FrameHeader.CalculateFrameHeaderSize(_receiveBuffer[_receiveBufferOffset + 1]); await EnsureDataAvailableOrReadAsync(frameHeaderSize, cancellationToken); _frameInProgress = new FrameHeader(new ArraySegment<byte>(_receiveBuffer, _receiveBufferOffset, frameHeaderSize)); _receiveBufferOffset += frameHeaderSize; _receiveBufferBytes -= frameHeaderSize; _frameBytesRemaining = _frameInProgress.DataLength; if (_frameInProgress.AreReservedSet()) { await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Unexpected reserved bits set", cancellationToken); } if (_unmaskInput != _frameInProgress.Masked) { await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Incorrect masking", cancellationToken); } if (!ValidateOpCode(_frameInProgress.OpCode)) { await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Invalid opcode: " + _frameInProgress.OpCode, cancellationToken); } if (_frameInProgress.IsControlFrame) { if (_frameBytesRemaining > 125) { await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Invalid control frame size", cancellationToken); } if (!_frameInProgress.Fin) { await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Fragmented control frame", cancellationToken); } if (_frameInProgress.OpCode == Constants.OpCodes.PingFrame || _frameInProgress.OpCode == Constants.OpCodes.PongFrame) { // Drain it, should be less than 125 bytes await EnsureDataAvailableOrReadAsync((int)_frameBytesRemaining, cancellationToken); if (_frameInProgress.OpCode == Constants.OpCodes.PingFrame) { await SendPongReplyAsync(cancellationToken); } _receiveBufferOffset += (int)_frameBytesRemaining; _receiveBufferBytes -= (int)_frameBytesRemaining; _frameBytesRemaining = 0; _frameInProgress = null; } } else if (_firstDataOpCode.HasValue && _frameInProgress.OpCode != Constants.OpCodes.ContinuationFrame) { // A data frame is already in progress, but this new frame is not a continuation frame. await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Expected a continuation frame: " + _frameInProgress.OpCode, cancellationToken); } }