From de6285466ce2a9a8151200e76601343166516c10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arkadiusz=20Rychli=C5=84ski?= Date: Fri, 19 Mar 2021 14:36:40 +0100 Subject: [PATCH] feat: Version for .netstandard2.0 Problems: - can't validate custom CA certificates --- arstomp/arstomp.csproj | 2 +- arstomp/src/Helpers.cs | 47 ++++++++++++++++++++++---------------- arstomp/src/StompClient.cs | 10 ++++---- arstomp/src/StompFrame.cs | 24 +++++++++---------- 4 files changed, 46 insertions(+), 37 deletions(-) diff --git a/arstomp/arstomp.csproj b/arstomp/arstomp.csproj index a5f1995..41d4021 100644 --- a/arstomp/arstomp.csproj +++ b/arstomp/arstomp.csproj @@ -2,7 +2,7 @@ library - netcoreapp3.1 + netstandard2.0 diff --git a/arstomp/src/Helpers.cs b/arstomp/src/Helpers.cs index 202114e..6b2ea86 100644 --- a/arstomp/src/Helpers.cs +++ b/arstomp/src/Helpers.cs @@ -9,7 +9,7 @@ using System.Text; namespace ArStomp { -internal static class Helpers + internal static class Helpers { /// /// Static instance of heartbeat frame @@ -27,25 +27,25 @@ internal static class Helpers internal static string GetCmdString(FrameType type) { - return type switch + switch (type) { - FrameType.Unknown => "UNKNOWN", - FrameType.Connected => "CONNECTED", - FrameType.Message => "MESSAGE", - FrameType.Receipt => "RECEIPT", - FrameType.Error => "ERROR", - FrameType.Stomp => "STOMP", - FrameType.Send => "SEND", - FrameType.Subscribe => "SUBSCRIBE", - FrameType.Unsubscribe => "UNSUBSCRIBE", - FrameType.Ack => "ACK", - FrameType.Nack => "NACK", - FrameType.Begin => "BEGIN", - FrameType.Commit => "COMMIT", - FrameType.Abort => "ABORT", - FrameType.Disconnect => "DISCONNECT", - FrameType.Heartbeat => "", - _ => "UNKNOWN" + case FrameType.Unknown: return "UNKNOWN"; + case FrameType.Connected: return "CONNECTED"; + case FrameType.Message: return "MESSAGE"; + case FrameType.Receipt: return "RECEIPT"; + case FrameType.Error: return "ERROR"; + case FrameType.Stomp: return "STOMP"; + case FrameType.Send: return "SEND"; + case FrameType.Subscribe: return "SUBSCRIBE"; + case FrameType.Unsubscribe: return "UNSUBSCRIBE"; + case FrameType.Ack: return "ACK"; + case FrameType.Nack: return "NACK"; + case FrameType.Begin: return "BEGIN"; + case FrameType.Commit: return "COMMIT"; + case FrameType.Abort: return "ABORT"; + case FrameType.Disconnect: return "DISCONNECT"; + case FrameType.Heartbeat: return ""; + default: return "UNKNOWN"; }; } private static async Task GetMessage(MemoryStream output, ClientWebSocket ws, CancellationToken cancellationToken) @@ -148,7 +148,7 @@ internal static class Helpers throw new Exception("Cannot parse header"); } var key = line.Substring(0, colon); - var value = line[(colon + 1)..]; + var value = line.Substring(colon + 1); frame.Headers[key.ToLower()] = value; line = reader.ReadLine().TrimEnd(); // next header @@ -180,4 +180,11 @@ internal static class Helpers return frame; } } + internal static class Backports + { + public static void WriteWholeArray(this MemoryStream stream, byte[] data) + { + stream.Write(data, 0, data.Length); + } + } } diff --git a/arstomp/src/StompClient.cs b/arstomp/src/StompClient.cs index 7fec390..9f5e162 100644 --- a/arstomp/src/StompClient.cs +++ b/arstomp/src/StompClient.cs @@ -40,7 +40,9 @@ namespace ArStomp if (certCollection != null && certCollection.Count > 0) { this.certCollection = certCollection; - ws.Options.RemoteCertificateValidationCallback = RemoteCertificateValidationCallback; + + // TODO find alternative method in case of .netstandard2.0 + // ws.Options.RemoteCertificateValidationCallback = RemoteCertificateValidationCallback; } } @@ -74,7 +76,7 @@ namespace ArStomp (sslPolicyErrors & (SslPolicyErrors.RemoteCertificateNotAvailable)) > 0 ) return false; // last certificate in chain should be one of our trust anchors - X509Certificate2 projectedRootCert = chain.ChainElements[^1].Certificate; + X509Certificate2 projectedRootCert = chain.ChainElements[chain.ChainElements.Count - 1].Certificate; // check if server's root ca is one of our trusted bool anytrusted = false; foreach (var cert in certCollection) @@ -97,7 +99,7 @@ namespace ArStomp { if (frame.Body != null) { - reason = Encoding.UTF8.GetString(frame.Body); + reason = Encoding.UTF8.GetString(frame.Body.Array, frame.Body.Offset, frame.Body.Count); } } throw new Exception($"Unexpected frame '{frame.Type}'. Message from server: {reason}"); @@ -138,7 +140,7 @@ namespace ArStomp /// queue o exchange (eg /exchange/name/routing-key in case of RabbitMQ) /// property correlationId for the message /// content of the message - public ValueTask Send(string destination, string correlationId, byte[] body) + public Task Send(string destination, string correlationId, byte[] body) { var ct = Token.Token; diff --git a/arstomp/src/StompFrame.cs b/arstomp/src/StompFrame.cs index 3d812eb..780e420 100644 --- a/arstomp/src/StompFrame.cs +++ b/arstomp/src/StompFrame.cs @@ -68,7 +68,7 @@ namespace ArStomp return sb.ToString(); } - internal ValueTask Serialize(ClientWebSocket ws, CancellationToken cancellationToken) + internal Task Serialize(ClientWebSocket ws, CancellationToken cancellationToken) { var utf8 = Encoding.UTF8; var EOL = utf8.GetBytes("\n"); @@ -78,29 +78,29 @@ namespace ArStomp // write command var cmd = Helpers.GetCmdString(Type); - stream.Write(utf8.GetBytes(cmd)); - stream.Write(EOL); + stream.WriteWholeArray(utf8.GetBytes(cmd)); + stream.WriteWholeArray(EOL); // write headers foreach (var i in Headers) { - stream.Write(utf8.GetBytes(i.Key)); - stream.Write(COLON); - stream.Write(utf8.GetBytes(i.Value)); - stream.Write(EOL); + stream.WriteWholeArray(utf8.GetBytes(i.Key)); + stream.WriteWholeArray(COLON); + stream.WriteWholeArray(utf8.GetBytes(i.Value)); + stream.WriteWholeArray(EOL); } // write empty line - stream.Write(EOL); + stream.WriteWholeArray(EOL); // write body if (Body != null && Body.Count > 0) { - stream.Write(Body); + stream.Write(Body.Array, Body.Offset, Body.Count); } // write NUL character - stream.Write(NUL); + stream.WriteWholeArray(NUL); stream.Flush(); var array = stream.GetBuffer(); if (StompClient.Debug) Console.WriteLine(">>>\n{0}\n>>>\n", this); - return ws.SendAsync(array.AsMemory(0, (int)stream.Position), WebSocketMessageType.Binary, true, cancellationToken); + return ws.SendAsync(new ArraySegment(array, 0, (int)stream.Position), WebSocketMessageType.Binary, true, cancellationToken); } } @@ -124,7 +124,7 @@ namespace ArStomp Headers["reply-to"] = "/temp-queue/rpc-replies"; if (correlationId != null) Headers["correlation-id"] = correlationId; Headers["content-length"] = body.Length.ToString(); - Body = body; + Body = new ArraySegment(body, 0, body.Length); } }