Beispiel #1
0
        /// <summary>
        /// Handle request request and get the response
        /// </summary>
        /// <param name="service">The service which will handle the request.</param>
        /// <param name="request">The request to handle.</param>
        /// <returns>The response for the request.</returns>
        protected async Task <JsonRpcResponse> GetResponseAsync(JsonRpcService service, JsonRpcRequest request)
        {
            JsonRpcResponse response = null;

            try
            {
                var rpcCall = service.GetRpcCall(request.Method);
                if (rpcCall == null)
                {
                    throw new MethodNotFoundException($"Method: {request.Method} not found.");
                }
                var arguments = await JsonRpcCodec.DecodeArgumentsAsync(request.Params, rpcCall.Parameters).ConfigureAwait(false);

                //From here we got the response id.
                response = new JsonRpcResponse(request.Id);
                //The parser will add context into the args, so the final count is parameter count + 1.
                if (arguments.Length == rpcCall.Parameters.Count)
                {
                    try
                    {
                        var result = await rpcCall.Call(arguments).ConfigureAwait(false);

                        if (request.IsNotification)
                        {
                            return(null);
                        }
                        response.WriteResult(result);
                    }
                    catch (Exception ex)
                    {
                        var argumentString = new StringBuilder();
                        argumentString.Append(Environment.NewLine);
                        var index = 0;
                        foreach (var argument in arguments)
                        {
                            argumentString.AppendLine($"[{index}] {argument}");
                        }

                        argumentString.Append(Environment.NewLine);
                        Logger.WriteError($"Call method {rpcCall.Name} with args:{argumentString} error :{ex.Format()}");
                        response.WriteResult(new InternalErrorException());
                    }
                }
                else
                {
                    throw new InvalidParamsException("Argument count is not matched");
                }
            }
            catch (Exception ex)
            {
                response ??= new JsonRpcResponse();
                if (ex is RpcException rpcException)
                {
                    Logger.WriteError($"Handle request {request} error: {rpcException.Format()}");
                    response.WriteResult(rpcException);
                }
                else
                {
                    Logger.WriteError($"Handle request {request} error: {ex.Format()}");
                    var serverError = new InternalErrorException();
                    response.WriteResult(serverError);
                }
            }
            return(response);
        }
Beispiel #2
0
        /// <summary>
        /// Handle connected request and return result.
        /// </summary>
        /// <param name="context">The http context to handle.</param>
        /// <param name="router">The router to dispatch the request data.</param>
        /// <param name="cancellationToken">The cancellation token which can cancel this method.</param>
        /// <returns>Void</returns>
        protected async Task HandleContextAsync(IJsonRpcHttpContext context, IJsonRpcRouter router, CancellationToken cancellationToken = default)
        {
            var httpMethod  = context.GetRequestHttpMethod();
            var requestPath = context.GetRequestPath();

            Logger.WriteVerbose($"Handle request [{httpMethod}]: {requestPath}");
            try
            {
                var serviceName = GetRpcServiceName(requestPath);
                if (string.IsNullOrEmpty(serviceName))
                {
                    Logger.WriteWarning($"Service for request: {requestPath} not found.");
                    throw new HttpException((int)HttpStatusCode.ServiceUnavailable, "Service does not exist.");
                }

                if (httpMethod == "get")
                {
                    var smdRequest = false;
                    var smdIndex   = serviceName.LastIndexOf(".smd", StringComparison.InvariantCultureIgnoreCase);
                    if (smdIndex != -1)
                    {
                        serviceName = serviceName.Substring(0, smdIndex);
                        smdRequest  = true;
                    }

                    if (!router.ServiceExists(serviceName))
                    {
                        Logger.WriteWarning($"Service for request: {requestPath} not found.");
                        throw new HttpException((int)HttpStatusCode.ServiceUnavailable, $"Service [{serviceName}] does not exist.");
                    }

                    if (SmdEnabled && smdRequest)
                    {
                        try
                        {
                            var smdData = await router.GetServiceSmdData(serviceName);
                            await WriteSmdDataAsync(context, smdData, cancellationToken).ConfigureAwait(false);
                        }
                        catch (Exception ex)
                        {
                            throw new HttpException((int)HttpStatusCode.InternalServerError, ex.Message);
                        }
                    }
                    else
                    {
                        throw new HttpException((int)HttpStatusCode.NotFound, $"Resource for {requestPath} does not exist.");
                    }
                }
                else if (httpMethod == "post")
                {
                    if (!router.ServiceExists(serviceName))
                    {
                        Logger.WriteWarning($"Service for request: {requestPath} not found.");
                        throw new ServerErrorException("Service does not exist.", $"Service [{serviceName}] does not exist.");
                    }

                    try
                    {
                        await DispatchAsync(context, router, serviceName, cancellationToken).ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        if (ex is RpcException)
                        {
                            throw;
                        }

                        throw new ServerErrorException("Internal server error.", ex.Message);
                    }
                }
                else
                {
                    throw new HttpException((int)HttpStatusCode.MethodNotAllowed, $"Invalid http-method:{httpMethod}");
                }
            }
            catch (Exception ex)
            {
                Logger.WriteError($"Handle request {requestPath} error: {ex.Message}");
                if (ex is HttpException httpException)
                {
                    await WriteHttpExceptionAsync(context, httpException, cancellationToken).ConfigureAwait(false);
                }
                else
                {
                    var response = new JsonRpcResponse();
                    if (ex is RpcException rpcException)
                    {
                        response.WriteResult(rpcException);
                    }
                    else
                    {
                        var serverError =
                            new InternalErrorException($"Handle request {requestPath} error: {ex.Message}");
                        response.WriteResult(serverError);
                    }

                    await WriteRpcResponsesAsync(context, new[] { response }, cancellationToken).ConfigureAwait(false);
                }
            }
            finally
            {
                context.Close();
            }
        }