From e33544dd2df99542eefd35fd22a1ce044e07a462 Mon Sep 17 00:00:00 2001 From: Luke Bakken Date: Wed, 12 Feb 2025 11:54:34 -0800 Subject: [PATCH] Fix #1777 Fixes #1777 * Adds a test that requires `PossibleAuthenticationFailureException` when attempting to log into RabbitMQ using invalid credentials. * Fix the issue by calling `ClosedViaPeerAsync` _after_ sending the `connection.close-ok` response to the broker. --- projects/RabbitMQ.Client/Impl/Channel.cs | 11 ++++++++--- .../Test/Integration/GH/TestGitHubIssues.cs | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/projects/RabbitMQ.Client/Impl/Channel.cs b/projects/RabbitMQ.Client/Impl/Channel.cs index 0538107f2..fb4d79b91 100644 --- a/projects/RabbitMQ.Client/Impl/Channel.cs +++ b/projects/RabbitMQ.Client/Impl/Channel.cs @@ -793,13 +793,18 @@ protected async Task HandleConnectionCloseAsync(IncomingCommand cmd, Cance var reason = new ShutdownEventArgs(ShutdownInitiator.Peer, method._replyCode, method._replyText, method._classId, method._methodId); try { - await Session.Connection.ClosedViaPeerAsync(reason, cancellationToken) - .ConfigureAwait(false); - + /* + * rabbitmq-dotnet-client#1777 + * Send the connection.close-ok message prior to closing within the client, + * because ClosedViaPeerAsync will stop the main loop + */ var replyMethod = new ConnectionCloseOk(); await ModelSendAsync(in replyMethod, cancellationToken) .ConfigureAwait(false); + await Session.Connection.ClosedViaPeerAsync(reason, cancellationToken) + .ConfigureAwait(false); + SetCloseReason(Session.Connection.CloseReason!); } catch (IOException) diff --git a/projects/Test/Integration/GH/TestGitHubIssues.cs b/projects/Test/Integration/GH/TestGitHubIssues.cs index f288c2822..45ca4e8f0 100644 --- a/projects/Test/Integration/GH/TestGitHubIssues.cs +++ b/projects/Test/Integration/GH/TestGitHubIssues.cs @@ -34,6 +34,7 @@ using System.Threading.Tasks; using RabbitMQ.Client; using RabbitMQ.Client.Events; +using RabbitMQ.Client.Exceptions; using Xunit; using Xunit.Abstractions; @@ -147,5 +148,22 @@ public async Task DisposeWhileCatchingTimeoutDeadlocksRepro_GH1759() await _conn.DisposeAsync(); } + + [Fact] + public async Task InvalidCredentialsShouldThrow_GH1777() + { + string userPass = Guid.NewGuid().ToString(); + + _connFactory = new ConnectionFactory + { + UserName = userPass, + Password = userPass + }; + + BrokerUnreachableException ex = + await Assert.ThrowsAnyAsync( + async () => await _connFactory.CreateConnectionAsync()); + Assert.IsAssignableFrom(ex.InnerException); + } } }