// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Buffers; using System.Collections.Generic; using System.Text; using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.SignalR.Protocol; using Newtonsoft.Json.Linq; namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests { public class VersionedJsonHubProtocol : IHubProtocol { private readonly int _version; private readonly JsonHubProtocol _innerProtocol; public VersionedJsonHubProtocol(int version) { _version = version; _innerProtocol = new JsonHubProtocol(); } public string Name => _innerProtocol.Name; public int Version => _version; public TransferFormat TransferFormat => _innerProtocol.TransferFormat; public int MinorVersion => 0; // not used in this test class, just for interface conformance public bool TryParseMessage(ref ReadOnlySequence input, IInvocationBinder binder, out HubMessage message) { var inputCopy = input; if (!TryParseMessage(ref input, out var payload)) { message = null; return false; } // Handle "new" call var json = Encoding.UTF8.GetString(payload.ToArray()); var o = JObject.Parse(json); if ((int)o["type"] == int.MaxValue) { message = new InvocationMessage("NewProtocolMethodServer", Array.Empty()); return true; } // Handle "old" calls var result = _innerProtocol.TryParseMessage(ref inputCopy, binder, out message); input = inputCopy; return result; } public static bool TryParseMessage(ref ReadOnlySequence buffer, out ReadOnlySequence payload) { var position = buffer.PositionOf((byte)0x1e); if (position == null) { payload = default; return false; } payload = buffer.Slice(0, position.Value); // Skip record separator buffer = buffer.Slice(buffer.GetPosition(1, position.Value)); return true; } public void WriteMessage(HubMessage message, IBufferWriter output) { _innerProtocol.WriteMessage(message, output); } public ReadOnlyMemory GetMessageBytes(HubMessage message) { return _innerProtocol.GetMessageBytes(message); } public bool IsVersionSupported(int version) { // Support older clients return version <= _version; } } }