You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ta...@apache.org on 2023/05/09 22:59:56 UTC

[qpid-proton-dotnet] branch main updated: PROTON-2731 Validate timeout value passed to Receive early

This is an automated email from the ASF dual-hosted git repository.

tabish pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-proton-dotnet.git


The following commit(s) were added to refs/heads/main by this push:
     new bd1a0da  PROTON-2731 Validate timeout value passed to Receive early
bd1a0da is described below

commit bd1a0da76ba86a2f2ae9c85f13b8d74e8ca9017e
Author: Timothy Bish <ta...@gmail.com>
AuthorDate: Tue May 9 18:58:27 2023 -0400

    PROTON-2731 Validate timeout value passed to Receive early
    
    Prevent the event loop handler from getting blocked by unexpected error
    from the task API delay feature.
---
 .../Client/Implementation/ClientReceiver.cs        |  6 +++
 .../Client/Implementation/ClientStreamReceiver.cs  |  6 +++
 .../Client/Implementation/ClientBaseTestFixture.cs |  2 +-
 .../Client/Implementation/ClientReceiverTest.cs    | 47 +++++++++++++++++++++
 .../Implementation/ClientStreamReceiverTest.cs     | 49 +++++++++++++++++++++-
 5 files changed, 108 insertions(+), 2 deletions(-)

diff --git a/src/Proton.Client/Client/Implementation/ClientReceiver.cs b/src/Proton.Client/Client/Implementation/ClientReceiver.cs
index 0b840a1..5b7beea 100644
--- a/src/Proton.Client/Client/Implementation/ClientReceiver.cs
+++ b/src/Proton.Client/Client/Implementation/ClientReceiver.cs
@@ -89,6 +89,12 @@ namespace Apache.Qpid.Proton.Client.Implementation
                   {
                      if (timeout != TimeSpan.MaxValue)
                      {
+                        if (timeout.TotalMilliseconds > uint.MaxValue)
+                        {
+                           receive.TrySetException(new ArgumentOutOfRangeException(
+                              "Receive timeout must convert to a value less than UInt32.MaxValue Milliseconds"));
+                        }
+
                         session.Schedule(() =>
                         {
                            if (!receive.Task.IsCompleted)
diff --git a/src/Proton.Client/Client/Implementation/ClientStreamReceiver.cs b/src/Proton.Client/Client/Implementation/ClientStreamReceiver.cs
index 182a915..e099df5 100644
--- a/src/Proton.Client/Client/Implementation/ClientStreamReceiver.cs
+++ b/src/Proton.Client/Client/Implementation/ClientStreamReceiver.cs
@@ -100,6 +100,12 @@ namespace Apache.Qpid.Proton.Client.Implementation
                   {
                      if (timeout != TimeSpan.MaxValue)
                      {
+                        if (timeout.TotalMilliseconds > uint.MaxValue)
+                        {
+                           receive.TrySetException(new ArgumentOutOfRangeException(
+                              "Receive timeout must convert to a value less than UInt32.MaxValue Milliseconds"));
+                        }
+
                         session.Schedule(() =>
                         {
                            if (!receive.Task.IsCompleted)
diff --git a/test/Proton.Client.Tests/Client/Implementation/ClientBaseTestFixture.cs b/test/Proton.Client.Tests/Client/Implementation/ClientBaseTestFixture.cs
index 92eb8c0..14d2bca 100644
--- a/test/Proton.Client.Tests/Client/Implementation/ClientBaseTestFixture.cs
+++ b/test/Proton.Client.Tests/Client/Implementation/ClientBaseTestFixture.cs
@@ -46,7 +46,7 @@ namespace Apache.Qpid.Proton.Client.Implementation
          NLog.Targets.Target logconsole = new NLog.Targets.ConsoleTarget("logconsole");
 
          // Rules for mapping loggers to targets
-         //config.AddRule(NLog.LogLevel.Trace, NLog.LogLevel.Fatal, logconsole);
+         // config.AddRule(NLog.LogLevel.Trace, NLog.LogLevel.Fatal, logconsole);
          config.AddRule(NLog.LogLevel.Trace, NLog.LogLevel.Fatal, logfile);
 
          loggerFactory = LoggerFactory.Create(builder =>
diff --git a/test/Proton.Client.Tests/Client/Implementation/ClientReceiverTest.cs b/test/Proton.Client.Tests/Client/Implementation/ClientReceiverTest.cs
index 3a52d6f..fdb21f0 100644
--- a/test/Proton.Client.Tests/Client/Implementation/ClientReceiverTest.cs
+++ b/test/Proton.Client.Tests/Client/Implementation/ClientReceiverTest.cs
@@ -3137,6 +3137,53 @@ namespace Apache.Qpid.Proton.Client.Implementation
          }
       }
 
+      [Test]
+      public void TestDeliveryReadWithLongTimeoutValue()
+      {
+         byte[] payload = CreateEncodedMessage(new AmqpValue("Hello World"));
+
+         using (ProtonTestServer peer = new ProtonTestServer(loggerFactory))
+         {
+            peer.ExpectSASLAnonymousConnect();
+            peer.ExpectOpen().Respond();
+            peer.ExpectBegin().Respond();
+            peer.ExpectAttach().OfReceiver().Respond();
+            peer.ExpectFlow().WithLinkCredit(10);
+            peer.RemoteTransfer().WithHandle(0)
+                                 .WithDeliveryId(0)
+                                 .WithDeliveryTag(new byte[] { 1 })
+                                 .WithMore(false)
+                                 .WithSettled(true)
+                                 .WithMessageFormat(0)
+                                 .WithPayload(payload).AfterDelay(20).Queue();
+            peer.Start();
+
+            string remoteAddress = peer.ServerAddress;
+            int remotePort = peer.ServerPort;
+
+            logger.LogInformation("Test started, peer listening on: {0}:{1}", remoteAddress, remotePort);
+
+            IClient container = IClient.Create();
+            IConnection connection = container.Connect(remoteAddress, remotePort);
+            ISession session = connection.OpenSession();
+            IReceiver receiver = session.OpenReceiver("test-queue");
+
+            Assert.Throws<ArgumentOutOfRangeException>(() => receiver.Receive(TimeSpan.FromDays(50)));
+
+            IDelivery delivery = receiver.Receive(TimeSpan.FromDays(49));
+            Assert.IsNotNull(delivery);
+
+            peer.WaitForScriptToComplete();
+            peer.ExpectDetach().Respond();
+            peer.ExpectClose().Respond();
+
+            receiver.Close();
+            connection.Close();
+
+            peer.WaitForScriptToComplete();
+         }
+      }
+
       private class AmqpJmsSelectorType : IDescribedType
       {
          private string selector;
diff --git a/test/Proton.Client.Tests/Client/Implementation/ClientStreamReceiverTest.cs b/test/Proton.Client.Tests/Client/Implementation/ClientStreamReceiverTest.cs
index e674829..ad0ce6b 100644
--- a/test/Proton.Client.Tests/Client/Implementation/ClientStreamReceiverTest.cs
+++ b/test/Proton.Client.Tests/Client/Implementation/ClientStreamReceiverTest.cs
@@ -4189,7 +4189,7 @@ namespace Apache.Qpid.Proton.Client.Implementation
 
             IClient container = IClient.Create();
             IConnection connection = container.Connect(remoteAddress, remotePort);
-            IStreamReceiver receiver = (IStreamReceiver)connection.OpenStreamReceiver("test-queue").OpenTask.Result;
+            IStreamReceiver receiver = connection.OpenStreamReceiver("test-queue").OpenTask.Result;
 
             byte[] payload = CreateEncodedMessage(new AmqpValue("Hello World"));
 
@@ -4233,5 +4233,52 @@ namespace Apache.Qpid.Proton.Client.Implementation
             peer.WaitForScriptToComplete();
          }
       }
+
+      [Test]
+      public void TestDeliveryReadWithLongTimeoutValue()
+      {
+         byte[] payload = CreateEncodedMessage(new AmqpValue("Hello World"));
+
+         using (ProtonTestServer peer = new ProtonTestServer(loggerFactory))
+         {
+            peer.ExpectSASLAnonymousConnect();
+            peer.ExpectOpen().Respond();
+            peer.ExpectBegin().Respond();
+            peer.ExpectAttach().OfReceiver().Respond();
+            peer.ExpectFlow().WithLinkCredit(10);
+            peer.RemoteTransfer().WithHandle(0)
+                                 .WithDeliveryId(0)
+                                 .WithDeliveryTag(new byte[] { 1 })
+                                 .WithMore(false)
+                                 .WithSettled(true)
+                                 .WithMessageFormat(0)
+                                 .WithPayload(payload).AfterDelay(20).Queue();
+            peer.Start();
+
+            string remoteAddress = peer.ServerAddress;
+            int remotePort = peer.ServerPort;
+
+            logger.LogInformation("Test started, peer listening on: {0}:{1}", remoteAddress, remotePort);
+
+            IClient container = IClient.Create();
+            IConnection connection = container.Connect(remoteAddress, remotePort);
+            IStreamReceiver receiver = connection.OpenStreamReceiver("test-queue");
+
+            Assert.Throws<ArgumentOutOfRangeException>(() => receiver.Receive(TimeSpan.FromDays(50)));
+
+            IStreamDelivery delivery = receiver.Receive(TimeSpan.FromDays(49));
+            Assert.IsNotNull(delivery);
+
+            peer.WaitForScriptToComplete();
+            peer.ExpectDetach().Respond();
+            peer.ExpectEnd().Respond();
+            peer.ExpectClose().Respond();
+
+            receiver.Close();
+            connection.Close();
+
+            peer.WaitForScriptToComplete();
+         }
+      }
    }
 }
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org