diff --git a/src/RabbitMQ.Next/Transport/Methods/Connection/SecureMethod.cs b/src/RabbitMQ.Next/Transport/Methods/Connection/SecureMethod.cs new file mode 100644 index 0000000..a5e8cf4 --- /dev/null +++ b/src/RabbitMQ.Next/Transport/Methods/Connection/SecureMethod.cs @@ -0,0 +1,16 @@ +using System; +using RabbitMQ.Next.Methods; + +namespace RabbitMQ.Next.Transport.Methods.Connection; + +public readonly struct SecureMethod : IIncomingMethod +{ + public SecureMethod(ReadOnlyMemory challenge) + { + this.Challenge = challenge; + } + + public MethodId MethodId => MethodId.ConnectionSecure; + + public ReadOnlyMemory Challenge { get; } +} \ No newline at end of file diff --git a/src/RabbitMQ.Next/Transport/Methods/Connection/SecureMethodParser.cs b/src/RabbitMQ.Next/Transport/Methods/Connection/SecureMethodParser.cs new file mode 100644 index 0000000..ee86782 --- /dev/null +++ b/src/RabbitMQ.Next/Transport/Methods/Connection/SecureMethodParser.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; + +namespace RabbitMQ.Next.Transport.Methods.Connection; + +internal class SecureMethodParser : IMethodParser +{ + public SecureMethod Parse(ReadOnlySpan payload) + { + payload.Read(out byte[] challenge); + + return new SecureMethod(challenge); + } +} \ No newline at end of file diff --git a/src/RabbitMQ.Next/Transport/Methods/Connection/SecureOkMethod.cs b/src/RabbitMQ.Next/Transport/Methods/Connection/SecureOkMethod.cs new file mode 100644 index 0000000..c8ebff9 --- /dev/null +++ b/src/RabbitMQ.Next/Transport/Methods/Connection/SecureOkMethod.cs @@ -0,0 +1,16 @@ +using System; +using RabbitMQ.Next.Methods; + +namespace RabbitMQ.Next.Transport.Methods.Connection; + +public readonly struct SecureOkMethod : IOutgoingMethod +{ + public SecureOkMethod(ReadOnlyMemory response) + { + this.Response = response; + } + + public MethodId MethodId => MethodId.ConnectionSecureOk; + + public ReadOnlyMemory Response { get; } +} \ No newline at end of file diff --git a/src/RabbitMQ.Next/Transport/Methods/Connection/SecureOkMethodFormatter.cs b/src/RabbitMQ.Next/Transport/Methods/Connection/SecureOkMethodFormatter.cs new file mode 100644 index 0000000..0d1ab2b --- /dev/null +++ b/src/RabbitMQ.Next/Transport/Methods/Connection/SecureOkMethodFormatter.cs @@ -0,0 +1,9 @@ +using System; + +namespace RabbitMQ.Next.Transport.Methods.Connection; + +internal class SecureOkMethodFormatter : IMethodFormatter +{ + public Span Write(Span destination, SecureOkMethod method) + => destination.Write(method.Response.Span); +} \ No newline at end of file diff --git a/src/RabbitMQ.Next/Transport/Methods/MethodRegistry.cs b/src/RabbitMQ.Next/Transport/Methods/MethodRegistry.cs index 631727b..189db04 100644 --- a/src/RabbitMQ.Next/Transport/Methods/MethodRegistry.cs +++ b/src/RabbitMQ.Next/Transport/Methods/MethodRegistry.cs @@ -31,6 +31,8 @@ void Register(MethodId methodId, IMethodFormatter formatter = // ConnectionMethods Register(MethodId.ConnectionStart, parser: new Connection.StartMethodParser()); Register(MethodId.ConnectionStartOk, formatter: new Connection.StartOkMethodFormatter()); + Register(MethodId.ConnectionSecure, parser: new Connection.SecureMethodParser()); + Register(MethodId.ConnectionSecureOk, formatter: new Connection.SecureOkMethodFormatter()); Register(MethodId.ConnectionTune, parser: new Connection.TuneMethodParser()); Register(MethodId.ConnectionTuneOk, formatter: new Connection.TuneOkMethodFormatter()); Register(MethodId.ConnectionOpen, formatter: new Connection.OpenMethodFormatter()); diff --git a/tests/RabbitMQ.Next.Tests/Transport/Methods/Connection/ModelTests.cs b/tests/RabbitMQ.Next.Tests/Transport/Methods/Connection/ModelTests.cs index d934e88..29346b5 100644 --- a/tests/RabbitMQ.Next.Tests/Transport/Methods/Connection/ModelTests.cs +++ b/tests/RabbitMQ.Next.Tests/Transport/Methods/Connection/ModelTests.cs @@ -47,7 +47,29 @@ public void StartOkMethod() Assert.Equal(locale, startOkMethod.Locale); Assert.Equal(clientProperties, startOkMethod.ClientProperties); } + + [Fact] + public void SecureMethod() + { + var challenge = "ping"u8.ToArray(); + + var secureMethod = new SecureMethod(challenge); + Assert.Equal(MethodId.ConnectionSecure, secureMethod.MethodId); + Assert.Equal(challenge, secureMethod.Challenge); + } + + [Fact] + public void SecureOkMethod() + { + var response = "pong"u8.ToArray(); + + var startOkMethod = new SecureOkMethod(response); + + Assert.Equal(MethodId.ConnectionSecureOk, startOkMethod.MethodId); + Assert.Equal(response, startOkMethod.Response); + } + [Fact] public void TuneMethod() { diff --git a/tests/RabbitMQ.Next.Tests/Transport/Methods/Connection/SecureMethodPayload.dat b/tests/RabbitMQ.Next.Tests/Transport/Methods/Connection/SecureMethodPayload.dat new file mode 100644 index 0000000..9693065 Binary files /dev/null and b/tests/RabbitMQ.Next.Tests/Transport/Methods/Connection/SecureMethodPayload.dat differ diff --git a/tests/RabbitMQ.Next.Tests/Transport/Methods/Connection/SecureOkMethodPayload.dat b/tests/RabbitMQ.Next.Tests/Transport/Methods/Connection/SecureOkMethodPayload.dat new file mode 100644 index 0000000..171899c Binary files /dev/null and b/tests/RabbitMQ.Next.Tests/Transport/Methods/Connection/SecureOkMethodPayload.dat differ diff --git a/tests/RabbitMQ.Next.Tests/Transport/Methods/Connection/SerializationTests.cs b/tests/RabbitMQ.Next.Tests/Transport/Methods/Connection/SerializationTests.cs index d023c96..51f6f2f 100644 --- a/tests/RabbitMQ.Next.Tests/Transport/Methods/Connection/SerializationTests.cs +++ b/tests/RabbitMQ.Next.Tests/Transport/Methods/Connection/SerializationTests.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using RabbitMQ.Next.Tests.Mocks; using RabbitMQ.Next.Transport.Methods.Connection; @@ -54,6 +55,14 @@ public void StartOkMethodFormatter() this.TestFormatter(method); } + [Fact] + public void SecureMethodParser() + => this.TestParser(new SecureMethod("ping"u8.ToArray()), new SecureMethodComparer()); + + [Fact] + public void SecureOkMethodFormatter() + => this.TestFormatter(new SecureOkMethod("pong"u8.ToArray())); + [Fact] public void TuneMethodParser() => this.TestParser(new TuneMethod(2047, 131072, 60)); @@ -110,4 +119,13 @@ public int GetHashCode(StartMethod obj) return HashCode.Combine(obj.VersionMajor, obj.VersionMinor, obj.ServerProperties, obj.Mechanisms, obj.Locales); } } + + private class SecureMethodComparer : IEqualityComparer + { + public bool Equals(SecureMethod x, SecureMethod y) + => x.Challenge.Span.SequenceEqual(y.Challenge.Span); + + public int GetHashCode(SecureMethod obj) + => obj.Challenge.GetHashCode(); + } } \ No newline at end of file diff --git a/tests/RabbitMQ.Next.Tests/Transport/Methods/SerializationTestBase.cs b/tests/RabbitMQ.Next.Tests/Transport/Methods/SerializationTestBase.cs index 0b7d5d2..24624be 100644 --- a/tests/RabbitMQ.Next.Tests/Transport/Methods/SerializationTestBase.cs +++ b/tests/RabbitMQ.Next.Tests/Transport/Methods/SerializationTestBase.cs @@ -39,7 +39,7 @@ protected void TestParser(TMethod method, IEqualityComparer co var payload = Helpers.GetFileContent(payloadResName); var data = parser.Parse(payload); - + Assert.Equal(method, data, comparer); } } \ No newline at end of file