Example #1
0
		public static async Task Run()
		{
			AuthenticationHeaderValue authHeaderValue = AuthenticationHeaderValue.Parse("Basic R2VrY3RlazpXZWxjMG1lIQ==");
			RpcClient client = new RpcClient(new Uri("http://localhost:62390/RpcApi/"), authHeaderValue);
			RpcRequest request = new RpcRequest("Id1", "CharacterCount", "Test");
			RpcResponse response = await client.SendRequestAsync(request, "Strings");

			List<RpcRequest> requests = new List<RpcRequest>
				{
					request,
					new RpcRequest("id2", "CharacterCount", "Test2"),
					new RpcRequest("id3", "CharacterCount", "Test23")
				};
			List<RpcResponse> bulkResponse = await client.SendBulkRequestAsync(requests, "Strings");

			IntegerFromSpace responseValue = response.GetResult<IntegerFromSpace>();
			if (responseValue == null)
			{
				Console.WriteLine("null");
			}
			else
			{
				Console.WriteLine(responseValue.Test);
			}
		}
        public override async Task<RpcResponse> InterceptSendRequestAsync(Func<RpcRequest, string, Task<RpcResponse>> interceptedSendRequestAsync, RpcRequest request, string route = null)
        {
          
            if (request.Method == "eth_accounts")
            {
                return BuildResponse(new string[] { "hello", "hello2"}, route);
            }

            if (request.Method == "eth_getCode")
            {
                return BuildResponse("the code", route);
            }
            return await interceptedSendRequestAsync(request, route);
        }
Example #3
0
 public static RpcRequest WithNoParameters(string method, RpcId id = default)
 {
     return(RpcRequest.WithParameters(method, default, id));
Example #4
0
 public static RpcRequest WithNoParameters(string id, string method)
 {
     return(RpcRequest.ConvertInternal(new RpcId(id), method, null, null));
 }
 public abstract Task<RpcResponse> InterceptSendRequestAsync(
     Func<RpcRequest, string, Task<RpcResponse>> interceptedSendRequestAsync, RpcRequest request,
     string route = null);
Example #6
0
		/// <summary>
		/// Call the incoming Rpc request method and gives the appropriate response
		/// </summary>
		/// <param name="request">Rpc request</param>
		/// <param name="route">Rpc route that applies to the current request</param>
		/// <param name="httpContext">The context of the current http request</param>
		/// <param name="jsonSerializerSettings">Json serialization settings that will be used in serialization and deserialization for rpc requests</param>
		/// <returns>An Rpc response for the request</returns>
		public async Task<RpcResponse> InvokeRequestAsync(RpcRequest request, RpcRoute route, HttpContext httpContext, JsonSerializerSettings jsonSerializerSettings = null)
		{
			try
			{
				if (request == null)
				{
					throw new ArgumentNullException(nameof(request));
				}
				if (route == null)
				{
					throw new ArgumentNullException(nameof(route));
				}
			}
			catch (ArgumentNullException ex) // Dont want to throw any exceptions when doing async requests
			{
				return this.GetUnknownExceptionReponse(request, ex);
			}

			this.logger?.LogDebug($"Invoking request with id '{request.Id}'");
			RpcResponse rpcResponse;
			try
			{
				if (!string.Equals(request.JsonRpcVersion, JsonRpcContants.JsonRpcVersion))
				{
					throw new RpcInvalidRequestException($"Request must be jsonrpc version '{JsonRpcContants.JsonRpcVersion}'");
				}

				object[] parameterList;
				RpcMethod rpcMethod = this.GetMatchingMethod(route, request, out parameterList, httpContext.RequestServices, jsonSerializerSettings);

				bool isAuthorized = await this.IsAuthorizedAsync(rpcMethod, httpContext);

				if (isAuthorized)
				{

					this.logger?.LogDebug($"Attempting to invoke method '{request.Method}'");
					object result = await rpcMethod.InvokeAsync(parameterList);
					this.logger?.LogDebug($"Finished invoking method '{request.Method}'");

					JsonSerializer jsonSerializer = JsonSerializer.Create(jsonSerializerSettings);
					if (result is IRpcMethodResult)
					{
						this.logger?.LogTrace($"Result is {nameof(IRpcMethodResult)}.");
						rpcResponse = ((IRpcMethodResult)result).ToRpcResponse(request.Id, obj => JToken.FromObject(obj, jsonSerializer));
					}
					else
					{
						this.logger?.LogTrace($"Result is plain object.");
						JToken resultJToken = result != null ? JToken.FromObject(result, jsonSerializer) : null;
						rpcResponse = new RpcResponse(request.Id, resultJToken);
					}
				}
				else
				{
					var authError = new RpcError(RpcErrorCode.InvalidRequest, "Unauthorized");
					rpcResponse = new RpcResponse(request.Id, authError);
				}
			}
			catch (RpcException ex)
			{
				this.logger?.LogException(ex, "An Rpc error occurred. Returning an Rpc error response");
				RpcError error = new RpcError(ex, this.serverConfig.Value.ShowServerExceptions);
				rpcResponse = new RpcResponse(request.Id, error);
			}
			catch (Exception ex)
			{
				rpcResponse = this.GetUnknownExceptionReponse(request, ex);
			}

			if (request.Id != null)
			{
				this.logger?.LogDebug($"Finished request with id '{request.Id}'");
				//Only give a response if there is an id
				return rpcResponse;
			}
			this.logger?.LogDebug($"Finished request with no id. Not returning a response");
			return null;
		}
Example #7
0
		/// <summary>
		/// Finds the matching Rpc method for the current request
		/// </summary>
		/// <param name="route">Rpc route for the current request</param>
		/// <param name="request">Current Rpc request</param>
		/// <param name="parameterList">Paramter list parsed from the request</param>
		/// <param name="serviceProvider">(Optional)IoC Container for rpc method controllers</param>
		/// <param name="jsonSerializerSettings">Json serialization settings that will be used in serialization and deserialization for rpc requests</param>
		/// <returns>The matching Rpc method to the current request</returns>
		private RpcMethod GetMatchingMethod(RpcRoute route, RpcRequest request, out object[] parameterList, IServiceProvider serviceProvider = null, JsonSerializerSettings jsonSerializerSettings = null)
		{
			if (route == null)
			{
				throw new ArgumentNullException(nameof(route));
			}
			if (request == null)
			{
				throw new ArgumentNullException(nameof(request));
			}
			this.logger?.LogDebug($"Attempting to match Rpc request to a method '{request.Method}'");
			List<RpcMethod> methods = DefaultRpcInvoker.GetRpcMethods(route, serviceProvider, jsonSerializerSettings);

			//Case insenstive check for hybrid approach. Will check for case sensitive if there is ambiguity
			methods = methods
				.Where(m => string.Equals(m.Method, request.Method, StringComparison.OrdinalIgnoreCase))
				.ToList();

			RpcMethod rpcMethod = null;
			parameterList = null;
			int originalMethodCount = methods.Count;
			if (methods.Count > 0)
			{
				List<RpcMethod> potentialMatches = new List<RpcMethod>();
				foreach (RpcMethod method in methods)
				{
					bool matchingMethod;
					if (request.ParameterMap != null)
					{
						matchingMethod = method.HasParameterSignature(request.ParameterMap, out parameterList);
					}
					else
					{
						matchingMethod = method.HasParameterSignature(request.ParameterList);
						parameterList = request.ParameterList;
					}
					if (matchingMethod)
					{
						potentialMatches.Add(method);
					}
				}

				if (potentialMatches.Count > 1)
				{
					//Try to remove ambiguity with case sensitive check
					potentialMatches = potentialMatches
						.Where(m => string.Equals(m.Method, request.Method, StringComparison.Ordinal))
						.ToList();
					if (potentialMatches.Count != 1) 
					{
						this.logger?.LogError("More than one method matched the rpc request. Unable to invoke due to ambiguity.");
						throw new RpcMethodNotFoundException();
					}
				}

				if (potentialMatches.Count == 1)
				{
					rpcMethod = potentialMatches.First();
				}
			}
			if (rpcMethod == null)
			{
				this.logger?.LogError("No methods matched request.");
				throw new RpcMethodNotFoundException();
			}
			this.logger?.LogDebug("Request was matched to a method");
			return rpcMethod;
		}
Example #8
0
		/// <summary>
		/// Converts an unknown caught exception into a Rpc response
		/// </summary>
		/// <param name="request">Current Rpc request</param>
		/// <param name="ex">Unknown exception</param>
		/// <returns>Rpc error response from the exception</returns>
		private RpcResponse GetUnknownExceptionReponse(RpcRequest request, Exception ex)
		{
			this.logger?.LogException(ex, "An unknown error occurred. Returning an Rpc error response");

			RpcUnknownException exception = new RpcUnknownException("An internal server error has occurred", ex);
			RpcError error = new RpcError(exception, this.serverConfig.Value.ShowServerExceptions);
			if (request?.Id == null)
			{
				return null;
			}
			RpcResponse rpcResponse = new RpcResponse(request.Id, error);
			return rpcResponse;
		}