Пример #1
0
        private JsonRpcResponse ReceiveMessage(string message)
        {
            JsonRpcResponse response;
            long            messageId = 0;

            try
            {
                JsonRpcMessage jsonRpcMessage = JsonConvert.DeserializeObject <JsonRpcMessage>(message);
                messageId = jsonRpcMessage.Id;
                try
                {
                    response = new JsonRpcResponse(jsonRpcMessage.Id, TryCallMethod(jsonRpcMessage).Result);
                }
                catch (Exception e)
                {
                    throw e.InnerException;
                }
            }
            catch (Exception e)
            {
                response = e switch
                {
                    JsonSerializationException _ => new JsonRpcResponse(messageId, JsonRpcErrors.ParseError),
                    MethodNotFoundException _ => new JsonRpcResponse(messageId, JsonRpcErrors.MethodNotFound),
                    InvalidParametersException _ => new JsonRpcResponse(messageId, JsonRpcErrors.InvalidParams),
                    FormatException _ => new JsonRpcResponse(messageId, JsonRpcErrors.InvalidParams),
                    _ => new JsonRpcResponse(messageId, JsonRpcErrors.InternalError)
                };
            }
            return(response);
        }
Пример #2
0
        public void ExecuteNamedParamsTest()
        {
            Incubator inc = new Incubator();

            inc.Set(new Echo());
            string         id      = "A Value";
            JsonRpcRequest request = new JsonRpcRequest();

            request.Incubator = inc;
            string value = "hello there ".RandomLetters(8);

            request.Params            = JToken.Parse("{{'value': '{0}'}}"._Format(value));
            request.RpcParams.By.Name = request.Params;
            request.Method            = "Send";
            request.Id = id;

            IHttpContext context = GetPostContextWithInput(request.ToJson());

            request           = (JsonRpcRequest)JsonRpcMessage.Parse(context);
            request.Incubator = inc;

            JsonRpcResponse response = request.Execute();

            Expect.IsTrue(response.GetType().Equals(typeof(JsonRpcResponse)));
            Expect.AreEqual(response.Result, value);
            Expect.IsNull(response.Error);
            Expect.AreEqual(request.Id, response.Id);
            Expect.AreEqual(id, response.Id);
        }
Пример #3
0
    protected override ValueTask WriteCoreAsync(JsonRpcMessage content, CancellationToken cancellationToken)
    {
        var builder = new Sequence <byte>();

        this.Formatter.Serialize(builder, content);
        this.WrittenMessages.Enqueue(builder);
        return(default);
Пример #4
0
        /// <summary>
        /// Reads a distinct and complete message from the transport, waiting for one if necessary.
        /// </summary>
        /// <param name="cancellationToken">A token to cancel the read request.</param>
        /// <returns>The received message, or <c>null</c> if the underlying transport ends before beginning another message.</returns>
        /// <exception cref="InvalidOperationException">Thrown when <see cref="CanRead"/> returns <c>false</c>.</exception>
        /// <exception cref="System.IO.EndOfStreamException">Thrown if the transport ends while reading a message.</exception>
        /// <exception cref="OperationCanceledException">Thrown if <paramref name="cancellationToken"/> is canceled before a new message is received.</exception>
        /// <remarks>
        /// Implementations may assume this method is never called before any async result
        /// from a prior call to this method has completed.
        /// </remarks>
        public async ValueTask <JsonRpcMessage> ReadAsync(CancellationToken cancellationToken)
        {
            Verify.Operation(this.CanRead, "No receiving stream.");
            cancellationToken.ThrowIfCancellationRequested();
            Verify.NotDisposed(this);

            try
            {
                JsonRpcMessage result = await this.ReadCoreAsync(cancellationToken).ConfigureAwait(false);

                return(result);
            }
            catch (InvalidOperationException ex) when(cancellationToken.IsCancellationRequested)
            {
                // PipeReader.ReadAsync can throw InvalidOperationException in a race where PipeReader.Complete() has been
                // called but we haven't noticed the CancellationToken was canceled yet.
                throw new OperationCanceledException("Reading failed during cancellation.", ex, cancellationToken);
            }
            catch (ObjectDisposedException)
            {
                // If already canceled, throw that instead of ObjectDisposedException.
                cancellationToken.ThrowIfCancellationRequested();
                throw;
            }
        }
        protected override ValueTask SendAsync(JsonRpcMessage message, CancellationToken cancellationToken)
        {
            if (message is JsonRpcRequest request)
            {
                Assert.True(request.TrySetTopLevelProperty <int>(MessageOrderPropertyName, this.messageCounter++));
            }

            return(base.SendAsync(message, cancellationToken));
        }
Пример #6
0
        private void TryConvertParameters(JsonRpcMessage message, MethodInfo methodInfo, out object[] parameters)
        {
            ParameterInfo[] parameterInfos = methodInfo.GetParameters();
            parameters = new object[parameterInfos.Length];

            for (int i = 0; i < parameterInfos.Length; i++)
            {
                parameters[i] = message.Params[i].ToObject(parameterInfos[i].ParameterType);
            }
        }
Пример #7
0
 public static string ToJson(this JsonRpcMessage jsonRpcMessage)
 {
     return(JsonConvert.SerializeObject(jsonRpcMessage,
                                        Formatting.None,
                                        new JsonSerializerSettings
     {
         NullValueHandling = NullValueHandling.Ignore,
         StringEscapeHandling = StringEscapeHandling.Default
     }));
 }
Пример #8
0
        public void ParseRequestArrayShouldReturnRpcBatch()
        {
            IRequest request = A.Fake <IRequest>();

            A.CallTo <string>(() => request.HttpMethod).Returns("POST");
            A.CallTo <Stream>(() => request.InputStream).Returns(GetRequestBatch());
            IJsonRpcRequest msg = JsonRpcMessage.Parse(request);

            Expect.IsInstanceOfType <JsonRpcBatch>(msg);
        }
Пример #9
0
        public void ParseRequestWithoutIdShouldReturnNotification()
        {
            IRequest request = A.Fake <IRequest>();

            A.CallTo <string>(() => request.HttpMethod).Returns("POST");
            A.CallTo <Stream>(() => request.InputStream).Returns(GetNotificationStream());
            IJsonRpcRequest msg = JsonRpcMessage.Parse(request);

            Expect.IsInstanceOfType <JsonRpcNotification>(msg);
        }
Пример #10
0
        /// <inheritdoc/>
        protected override void Write(JsonRpcMessage content, CancellationToken cancellationToken)
        {
            if (this.prefixingWriter == null)
            {
                this.prefixingWriter = new PrefixingBufferWriter <byte>(this.Writer, sizeof(int));
            }

            // Write out the actual message content, counting all written bytes.
            this.Formatter.Serialize(this.prefixingWriter, content);

            // Now go back and fill in the header with the actual content length.
            Utilities.Write(this.prefixingWriter.Prefix.Span, checked ((int)this.prefixingWriter.Length));
            this.prefixingWriter.Commit();
        }
Пример #11
0
    public async Task Ctor_AcceptsNullReceivingStream()
    {
        var handler = new MyStreamMessageHandler(this.sendingStream, null, new MessagePackFormatter());

        Assert.False(handler.CanRead);
        Assert.True(handler.CanWrite);

        await Assert.ThrowsAsync <InvalidOperationException>(() => handler.ReadAsync(this.TimeoutToken).AsTask());

        JsonRpcMessage expected = CreateNotifyMessage();
        await handler.WriteAsync(expected, this.TimeoutToken);

        var actual = await handler.WrittenMessages.DequeueAsync(this.TimeoutToken);

        Assert.Equal(expected, actual);
    }
Пример #12
0
        /// <inheritdoc/>
        public void Serialize(IBufferWriter <byte> contentBuffer, JsonRpcMessage message)
        {
            var correctedMessage = ToValidRequest(message);

            switch (_serializerKind)
            {
            case MessagePackSerializerKind.LZ4MessagePackSerializer:
                LZ4MessagePackSerializer.Serialize(contentBuffer.AsStream(), correctedMessage, _resolver);
                return;

            case MessagePackSerializerKind.MessagePackSerializer:
                MessagePackSerializer.Serialize(contentBuffer.AsStream(), correctedMessage, _resolver);
                return;

            default:
                throw new InvalidOperationException("internal error");
            }
        }
Пример #13
0
        public void ParseRequestWithOrderedParams()
        {
            IRequest request = A.Fake <IRequest>();

            A.CallTo <string>(() => request.HttpMethod).Returns("POST");
            A.CallTo <Stream>(() => request.InputStream).Returns(GetRequestWithOrderedParamsStream());
            IJsonRpcRequest msg = JsonRpcMessage.Parse(request);

            Expect.IsInstanceOfType <JsonRpcRequest>(msg);
            JsonRpcRequest rpcRequest = (JsonRpcRequest)msg;

            Expect.IsTrue(rpcRequest.RpcParams.Ordered);
            Expect.IsTrue(rpcRequest.RpcParams.By.Position != null);
            Expect.IsFalse(rpcRequest.RpcParams.Named);
            Expect.IsTrue(rpcRequest.RpcParams.By.Name == null);
            Expect.IsNotNull(rpcRequest.Params);
            Expect.IsTrue(rpcRequest.Params.Is <JArray>(), "Params should have been a JArray");
        }
Пример #14
0
        /// <inheritdoc/>
        public void Serialize(IBufferWriter <byte> contentBuffer, JsonRpcMessage message)
        {
            if (message is JsonRpcRequest request && request.Arguments != null && request.ArgumentsList == null && !(request.Arguments is IReadOnlyDictionary <string, object>))
            {
                // This request contains named arguments, but not using a standard dictionary. Convert it to a dictionary so that
                // the parameters can be matched to the method we're invoking.
                request.Arguments = GetParamsObjectDictionary(request.Arguments);
            }

            if (this.compress)
            {
                LZ4MessagePackSerializer.Typeless.Serialize(contentBuffer.AsStream(), message);
            }
            else
            {
                MessagePackSerializer.Typeless.Serialize(contentBuffer.AsStream(), message);
            }
        }
        protected override async ValueTask <JsonRpcMessage> DispatchRequestAsync(JsonRpcRequest request, TargetMethod targetMethod, CancellationToken cancellationToken)
        {
            this.LastRequestDispatched = request;
            TaskCompletionSource <JsonRpcMessage>?completionTcs = null;

            if (this.EnableBuffering)
            {
                TaskCompletionSource <bool> signalTask = new TaskCompletionSource <bool>();
                completionTcs = new TaskCompletionSource <JsonRpcMessage>();
                this.requestSignalQueue.TryEnqueue((request, signalTask, completionTcs.Task));

                await signalTask.Task;
            }

            JsonRpcMessage result = await base.DispatchRequestAsync(request, targetMethod, cancellationToken);

            completionTcs?.SetResult(result);
            return(result);
        }
Пример #16
0
        public void ExecuteOrderedParamsTest()
        {
            Incubator inc = new Incubator();

            inc.Set(new Echo());
            string          value       = "hello there ".RandomLetters(8);
            object          id          = "some value";
            string          inputString = "{{'jsonrpc': '2.0', 'method': 'Send', 'id': '{0}', 'params': ['{1}']}}"._Format(id, value);
            IHttpContext    context     = GetPostContextWithInput(inputString);
            IJsonRpcRequest parsed      = JsonRpcMessage.Parse(context);
            JsonRpcRequest  request     = (JsonRpcRequest)parsed;

            request.Incubator = inc;
            JsonRpcResponse response = request.Execute();

            Expect.IsTrue(response.GetType().Equals(typeof(JsonRpcResponse)));
            Expect.AreEqual(value, response.Result);
            Expect.IsNull(response.Error);
            Expect.AreEqual(id, response.Id);
        }
Пример #17
0
        /// <inheritdoc/>
        protected override async ValueTask <JsonRpcMessage> ReadCoreAsync(CancellationToken cancellationToken)
        {
            var readResult = await this.ReadAtLeastAsync(4, allowEmpty : true, cancellationToken).ConfigureAwait(false);

            if (readResult.Buffer.Length == 0)
            {
                return(null);
            }

            ReadOnlySequence <byte> lengthBuffer = readResult.Buffer.Slice(0, 4);
            int length = Utilities.ReadInt32BE(lengthBuffer);

            this.Reader.AdvanceTo(lengthBuffer.End);

            readResult = await this.ReadAtLeastAsync(length, allowEmpty : false, cancellationToken).ConfigureAwait(false);

            ReadOnlySequence <byte> content = readResult.Buffer.Slice(0, length);
            JsonRpcMessage          message = this.Formatter.Deserialize(content);

            this.Reader.AdvanceTo(content.End);
            return(message);
        }
Пример #18
0
        /// <summary>
        /// Writes a message to the transport and flushes.
        /// </summary>
        /// <param name="content">The message to write.</param>
        /// <param name="cancellationToken">A token to cancel the write request.</param>
        /// <returns>A task that represents the asynchronous operation.</returns>
        /// <exception cref="InvalidOperationException">Thrown when <see cref="CanWrite"/> returns <c>false</c>.</exception>
        /// <exception cref="OperationCanceledException">Thrown if <paramref name="cancellationToken"/> is canceled before message transmission begins.</exception>
        /// <remarks>
        /// Implementations should expect this method to be invoked concurrently
        /// and use a queue to preserve message order as they are transmitted one at a time.
        /// </remarks>
        public async ValueTask WriteAsync(JsonRpcMessage content, CancellationToken cancellationToken)
        {
            Requires.NotNull(content, nameof(content));
            Verify.Operation(this.CanWrite, "No sending stream.");
            cancellationToken.ThrowIfCancellationRequested();
            Verify.NotDisposed(this);

            try
            {
                using (await this.sendingSemaphore.EnterAsync(cancellationToken).ConfigureAwait(false))
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    await this.WriteCoreAsync(content, cancellationToken).ConfigureAwait(false);

                    await this.FlushAsync(cancellationToken).ConfigureAwait(false);
                }
            }
            catch (ObjectDisposedException)
            {
                // If already canceled, throw that instead of ObjectDisposedException.
                cancellationToken.ThrowIfCancellationRequested();
                throw;
            }
        }
Пример #19
0
        // If message is a JsonRpcRequest and its Arguments is a paramter object,
        // converts the parameter object to a valid JSON-RPC parameter structure.
        private JsonRpcMessage ToValidRequest(JsonRpcMessage message)
        {
            if (!(message is JsonRpcRequest request))
            {
                return(message);
            }

            if (IsValidParameterStructure(request.Arguments))
            {
                return(message);
            }
            else
            {
                if (!_allowParameterObject)
                {
                    throw new NotSupportedException("This JsonRpcMessagePackFormatter is not configured to allow parameter objects.");
                }

                // NOTE: How a member of a parameter object is matched against a parameter of an RPC method
                //       is not a concern of serializers, but the concern of the StreamJsonRpc interface,
                //       introduced by the `InvokeWithParameterObjectAsync` contract.
                //
                //       By using Json.NET, we happen to implement this matching algorithm. During serialization
                //       every object is converted into a JSON object. Thus we can easily obtain
                //       serialized property names using JObject.Properties.
                //
                // Shallowly convert the parameter object to a Dictionary<string, object> before serialization.
                return(new JsonRpcRequest()
                {
                    Id = request.Id,
                    Method = request.Method,
                    Version = request.Version,
                    NamedArguments = ToParameterStructure(request.Arguments),
                });
            }
        }
 public void Serialize(IBufferWriter <byte> contentBuffer, JsonRpcMessage message)
 {
     throw new NotImplementedException();
 }
 public object GetJsonText(JsonRpcMessage message)
 {
     throw new NotImplementedException();
 }
Пример #22
0
 protected override ValueTask WriteCoreAsync(JsonRpcMessage message, CancellationToken cancellationToken)
 {
     this.WrittenMessages.Enqueue(message);
     return(default);
Пример #23
0
 /// <summary>
 /// Writes a message.
 /// </summary>
 /// <param name="content">The message to write.</param>
 /// <param name="cancellationToken">A token to cancel the transmission.</param>
 /// <returns>A task that represents the asynchronous write operation.</returns>
 protected abstract ValueTask WriteCoreAsync(JsonRpcMessage content, CancellationToken cancellationToken);
 public object GetJsonText(JsonRpcMessage message)
 {
     throw new NotSupportedException();
 }
Пример #25
0
 protected override ValueTask WriteCoreAsync(JsonRpcMessage content, CancellationToken cancellationToken)
 {
     Interlocked.Increment(ref this.WriteCoreCallCount);
     return(new ValueTask(this.WriteBlock.WaitAsync()));
 }
 public void Serialize(IBufferWriter <byte> bufferWriter, JsonRpcMessage message)
 {
     this.formatter.Serialize(bufferWriter, message);
 }
Пример #27
0
 /// <inheritdoc/>
 public object GetJsonText(JsonRpcMessage message) => MessagePackSerializer.ToJson <object>(message);
Пример #28
0
 public void Serialize(System.Buffers.IBufferWriter <byte> bufferWriter, JsonRpcMessage message)
 {
     throw new NotImplementedException();
 }
Пример #29
0
 protected override void Write(JsonRpcMessage content, CancellationToken cancellationToken)
 {
     throw new FileNotFoundException();
 }
Пример #30
0
 protected override ValueTask WriteCoreAsync(JsonRpcMessage content, CancellationToken cancellationToken)
 {
     this.WrittenMessages.Enqueue(this.Formatter.Serialize(content));
     return(default);