/// <exception cref="WrxTcpAuthorizationFailedException">Если авторизация не удалась.</exception>
        public static async ValueTask <T> AuthorizeAsync <T>(IPacketWriter <WrxPacket> requestWriter, IPacketReader <WrxPacket> responseReader, IAsyncWrxTcpHubAuthorizer <T> authorizer, ArrayPool <byte> byteArrayPool, CancellationToken cancellationToken = default)
        {
            using var requestPacket = new WrxPacket(0, WrxPacketAction.TcpAuthorizationRequest, 0, _zeroes.AsMemory());
            await requestWriter.WriteAsync(requestPacket, cancellationToken).ConfigureAwait(false);

            using var responsePacket = await responseReader.ReadAsync(cancellationToken).ConfigureAwait(false);

            var(_, responseAction, responseCommand, responseData) = responsePacket;

            if (responseAction != WrxPacketAction.TcpAuthorizationResponse)
            {
                throw new Exception("Invalid action.");
            }

            if (responseCommand != 0)
            {
                throw new Exception("Invalid command.");
            }

            var authorizationData = WrxTcpAuthorizationData.Read(responseData.Span);
            var info = await authorizer.ValidateDataAsync(authorizationData, cancellationToken).ConfigureAwait(false);

            using var acknowledgementPacket = new WrxPacket(1, WrxPacketAction.TcpAuthorizationRequest, 1, _zeroes.AsMemory());
            await requestWriter.WriteAsync(acknowledgementPacket, cancellationToken).ConfigureAwait(false);

            return(info);
        }
Exemplo n.º 2
0
        private async ValueTask <WrxPacket> ProcessPacketAsync(WrxPacket requestPacket, CancellationToken cancellationToken)
        {
            var(protocol, requestAction, command, requestData) = requestPacket;

            if (!TryGetActionEntry(requestAction, out var actionEntry))
            {
                throw new Exception("Unknown action.");
            }

            var responseAction = actionEntry.ResponseAction;

            if (!TryGetCommandEntry(command, out var commandEntry) || !actionEntry.CanProcessCommand(commandEntry))
            {
                return(CreateErrorPacket(responseAction, command, WrxPacketError.CommandNotSupported));
            }

            var errorDataSize    = WrxErrorData.GetSize(protocol);
            var responseDataSize = Math.Max(actionEntry.GetMaximumResponseDataSize(commandEntry), errorDataSize);
            var byteArray        = _byteArrayPool.Rent(responseDataSize);

            try
            {
                var responseData = byteArray.AsMemory();
                int count;

                try
                {
                    count = await actionEntry.ProcessCommandAsync(commandEntry, _commandHandler, requestData, responseData, cancellationToken).ConfigureAwait(false);
                }
                catch (WrxException ex)
                {
                    count = errorDataSize;
                    new WrxErrorData(command, ex.Error).Write(protocol, responseData.Span);
                    command = 0xFF;
                }

                return(new WrxPacket(protocol, responseAction, command, responseData[..count]));