diff --git a/projects/RabbitMQ.Client/client/api/IBasicProperties.cs b/projects/RabbitMQ.Client/client/api/IBasicProperties.cs
index c1ccc74349..16b4e477c4 100644
--- a/projects/RabbitMQ.Client/client/api/IBasicProperties.cs
+++ b/projects/RabbitMQ.Client/client/api/IBasicProperties.cs
@@ -121,9 +121,9 @@ public interface IBasicProperties : IContentHeader
string ReplyTo { get; set; }
///
- /// Convenience property; parses property using ,
+ /// Convenience property; parses property using ,
/// and serializes it using .
- /// Returns null if property cannot be parsed by .
+ /// Returns null if property cannot be parsed by .
///
PublicationAddress ReplyToAddress { get; set; }
diff --git a/projects/RabbitMQ.Client/client/api/PublicationAddress.cs b/projects/RabbitMQ.Client/client/api/PublicationAddress.cs
index 60fdbd0c80..9f819f8e7f 100644
--- a/projects/RabbitMQ.Client/client/api/PublicationAddress.cs
+++ b/projects/RabbitMQ.Client/client/api/PublicationAddress.cs
@@ -116,6 +116,32 @@ public static PublicationAddress Parse(string uriLikeString)
return null;
}
+ public static bool TryParse(string uriLikeString, out PublicationAddress result)
+ {
+ // Callers such as IBasicProperties.ReplyToAddress
+ // expect null result for invalid input.
+ // The regex.Match() throws on null arguments so we perform explicit check here
+ if (uriLikeString == null)
+ {
+ result = null;
+ return false;
+ }
+ else
+ {
+ try
+ {
+ var res = Parse(uriLikeString);
+ result = res;
+ return true;
+ }
+ catch
+ {
+ result = null;
+ return false;
+ }
+ }
+ }
+
///
/// Reconstruct the "uri" from its constituents.
///
diff --git a/projects/RabbitMQ.Client/client/impl/BasicProperties.cs b/projects/RabbitMQ.Client/client/impl/BasicProperties.cs
index b824801b83..05ffda72a2 100644
--- a/projects/RabbitMQ.Client/client/impl/BasicProperties.cs
+++ b/projects/RabbitMQ.Client/client/impl/BasicProperties.cs
@@ -109,13 +109,16 @@ public bool Persistent
public abstract string ReplyTo { get; set; }
///
- /// Convenience property; parses property using ,
+ /// Convenience property; parses property using ,
/// and serializes it using .
- /// Returns null if property cannot be parsed by .
+ /// Returns null if property cannot be parsed by .
///
public PublicationAddress ReplyToAddress
{
- get { return PublicationAddress.Parse(ReplyTo); }
+ get {
+ PublicationAddress.TryParse(ReplyTo, out var result);
+ return result;
+ }
set { ReplyTo = value.ToString(); }
}
diff --git a/projects/Unit/APIApproval.Approve.verified.txt b/projects/Unit/APIApproval.Approve.verified.txt
index f07a3050cd..3d8a9c9e03 100644
--- a/projects/Unit/APIApproval.Approve.verified.txt
+++ b/projects/Unit/APIApproval.Approve.verified.txt
@@ -483,6 +483,7 @@ namespace RabbitMQ.Client
public string RoutingKey { get; }
public override string ToString() { }
public static RabbitMQ.Client.PublicationAddress Parse(string uriLikeString) { }
+ public static bool TryParse(string uriLikeString, out RabbitMQ.Client.PublicationAddress result) { }
}
public class QueueDeclareOk
{
diff --git a/projects/Unit/TestBasicProperties.cs b/projects/Unit/TestBasicProperties.cs
index 3b7da08dc1..3693309c8e 100644
--- a/projects/Unit/TestBasicProperties.cs
+++ b/projects/Unit/TestBasicProperties.cs
@@ -52,7 +52,6 @@ public void TestPersistentPropertyChangesDeliveryMode_PersistentTrueDelivery2()
// Arrange
var subject = new Framing.BasicProperties
{
-
// Act
Persistent = true
};
@@ -120,5 +119,35 @@ public void TestNullableProperties_CanWrite(
Assert.AreEqual(isCorrelationIdPresent, propertiesFromStream.IsCorrelationIdPresent());
Assert.AreEqual(isMessageIdPresent, propertiesFromStream.IsMessageIdPresent());
}
+
+ [Test]
+ public void TestProperties_ReplyTo([Values(null, "foo_1", "fanout://name/key")] string replyTo)
+ {
+ // Arrange
+ var subject = new Framing.BasicProperties
+ {
+ // Act
+ ReplyTo = replyTo,
+ };
+
+ // Assert
+ bool isReplyToPresent = replyTo != null;
+ PublicationAddress result;
+ PublicationAddress.TryParse(replyTo, out result);
+ string replyToAddress = result?.ToString();
+ Assert.AreEqual(isReplyToPresent, subject.IsReplyToPresent());
+
+ var writer = new Impl.ContentHeaderPropertyWriter(new byte[1024]);
+ subject.WritePropertiesTo(ref writer);
+
+ // Read from Stream
+ var propertiesFromStream = new Framing.BasicProperties();
+ var reader = new Impl.ContentHeaderPropertyReader(writer.Memory.Slice(0, writer.Offset));
+ propertiesFromStream.ReadPropertiesFrom(ref reader);
+
+ Assert.AreEqual(replyTo, propertiesFromStream.ReplyTo);
+ Assert.AreEqual(isReplyToPresent, propertiesFromStream.IsReplyToPresent());
+ Assert.AreEqual(replyToAddress, propertiesFromStream.ReplyToAddress?.ToString());
+ }
}
}
diff --git a/projects/Unit/TestPropertiesClone.cs b/projects/Unit/TestPropertiesClone.cs
index f5827b5a0e..06be6fffea 100644
--- a/projects/Unit/TestPropertiesClone.cs
+++ b/projects/Unit/TestPropertiesClone.cs
@@ -68,10 +68,10 @@ private void TestBasicPropertiesClone(BasicProperties bp)
bp.ContentType = "foo_1";
bp.ContentEncoding = "foo_2";
bp.Headers = new Dictionary
- {
- { "foo_3", "foo_4" },
- { "foo_5", "foo_6" }
- };
+ {
+ { "foo_3", "foo_4" },
+ { "foo_5", "foo_6" }
+ };
bp.DeliveryMode = 2;
// Persistent also changes DeliveryMode's value to 2
bp.Persistent = true;
@@ -123,6 +123,7 @@ private void TestBasicPropertiesClone(BasicProperties bp)
Assert.AreEqual(12, bpClone.Priority);
Assert.AreEqual("foo_7", bpClone.CorrelationId);
Assert.AreEqual("foo_8", bpClone.ReplyTo);
+ Assert.AreEqual(null, bpClone.ReplyToAddress);
Assert.AreEqual("foo_9", bpClone.Expiration);
Assert.AreEqual("foo_10", bpClone.MessageId);
Assert.AreEqual(new AmqpTimestamp(123), bpClone.Timestamp);
@@ -141,10 +142,10 @@ private void TestBasicPropertiesNoneClone(BasicProperties bp)
bp.ContentType = "foo_1";
bp.ContentEncoding = "foo_2";
bp.Headers = new Dictionary
- {
- { "foo_3", "foo_4" },
- { "foo_5", "foo_6" }
- };
+ {
+ { "foo_3", "foo_4" },
+ { "foo_5", "foo_6" }
+ };
bp.DeliveryMode = 2;
// Persistent also changes DeliveryMode's value to 2
bp.Persistent = true;
diff --git a/projects/Unit/TestPublicationAddress.cs b/projects/Unit/TestPublicationAddress.cs
index 0d9b7ca924..7371959177 100644
--- a/projects/Unit/TestPublicationAddress.cs
+++ b/projects/Unit/TestPublicationAddress.cs
@@ -57,9 +57,29 @@ public void TestParseOk()
}
[Test]
- public void TestParseFail()
+ public void TestParseFailWithANE()
{
- Assert.IsNull(PublicationAddress.Parse("not a valid uri"));
+ Assert.That(()=> PublicationAddress.Parse(null), Throws.ArgumentNullException);
+ }
+
+ [Test]
+ public void TestParseFailWithUnparseableInput()
+ {
+ Assert.IsNull(PublicationAddress.Parse("not a valid URI"));
+ }
+
+ [Test]
+ public void TestTryParseFail()
+ {
+ PublicationAddress result;
+ PublicationAddress.TryParse(null, out result);
+ Assert.IsNull(result);
+
+ PublicationAddress.TryParse("not a valid URI", out result);
+ Assert.IsNull(result);
+
+ PublicationAddress.TryParse("}}}}}}}}", out result);
+ Assert.IsNull(result);
}
[Test]