/// <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); }
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]));