Microsoft.AspNetCore.WebSockets.Protocol.CommonWebSocket.ReadNextFrameAsync C# (CSharp) Method

ReadNextFrameAsync() private method

private ReadNextFrameAsync ( CancellationToken cancellationToken ) : Task
cancellationToken System.Threading.CancellationToken
return Task
        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);
            }
        }