Beispiel #1
0
        public static bool TryGetValue <T>(this IRpcParameter parameter, out T value)
        {
            bool parsed = parameter.TryGetValue(typeof(T), out object?v);

            if (parsed)
            {
                value = (T)v !;
                return(true);
            }
            value = default !;
Beispiel #2
0
 public RpcParameters(IRpcParameter parameter)
 {
     if (parameter == null)
     {
         throw new ArgumentNullException(nameof(parameter));
     }
     this.Value = new IRpcParameter[1] {
         parameter
     };
     this.IsDictionary = false;
 }
Beispiel #3
0
        private RpcRequestParseResult ParseResult(ref Utf8JsonReader jsonReader, Memory <byte> bytes)
        {
            RpcId         id         = default;
            string?       method     = null;
            RpcParameters?parameters = null;
            string?       rpcVersion = null;

            try
            {
                if (jsonReader.TokenType == JsonTokenType.StartObject)
                {
                    jsonReader.Read();
                }
                while (jsonReader.TokenType != JsonTokenType.EndObject)
                {
                    string propertyName = jsonReader.GetString();
                    jsonReader.Read();
                    switch (propertyName)
                    {
                    case JsonRpcContants.IdPropertyName:
                        switch (jsonReader.TokenType)
                        {
                        case JsonTokenType.String:
                            id = new RpcId(jsonReader.GetString());
                            break;

                        case JsonTokenType.Number:
                            if (!jsonReader.TryGetInt64(out long longId))
                            {
                                var idError = new RpcError(RpcErrorCode.ParseError, "Unable to parse rpc id as an integer");
                                return(RpcRequestParseResult.Fail(id, idError));
                            }
                            id = new RpcId(longId);
                            break;

                        default:
                            var error = new RpcError(RpcErrorCode.ParseError, "Unable to parse rpc id as a string or an integer");
                            return(RpcRequestParseResult.Fail(id, error));
                        }
                        break;

                    case JsonRpcContants.VersionPropertyName:
                        rpcVersion = jsonReader.GetString();
                        break;

                    case JsonRpcContants.MethodPropertyName:
                        method = jsonReader.GetString();
                        break;

                    case JsonRpcContants.ParamsPropertyName:
                        RpcParameters ps;
                        switch (jsonReader.TokenType)
                        {
                        case JsonTokenType.StartArray:
                            jsonReader.Read();
                            var list = new List <IRpcParameter>();
                            while (jsonReader.TokenType != JsonTokenType.EndArray)
                            {
                                IRpcParameter parameter = this.GetParameter(ref jsonReader, bytes);
                                list.Add(parameter);
                            }
                            //TODO array vs list?
                            ps = new RpcParameters(list.ToArray());
                            break;

                        case JsonTokenType.StartObject:
                            jsonReader.Read();
                            var dict = new Dictionary <string, IRpcParameter>();
                            while (jsonReader.TokenType != JsonTokenType.EndObject)
                            {
                                string key = jsonReader.GetString();
                                jsonReader.Read();
                                IRpcParameter parameter = this.GetParameter(ref jsonReader, bytes);
                                dict.Add(key, parameter);
                            }
                            ps = new RpcParameters(dict);
                            break;

                        default:
                            return(RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.InvalidRequest, "The request parameter format is invalid.")));
                        }
                        parameters = ps;
                        break;
                    }
                    jsonReader.Read();
                }

                if (string.IsNullOrWhiteSpace(method))
                {
                    return(RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.InvalidRequest, "The request method is required.")));
                }
                if (string.IsNullOrWhiteSpace(rpcVersion))
                {
                    return(RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.InvalidRequest, "The jsonrpc version must be specified.")));
                }
                if (!string.Equals(rpcVersion, "2.0", StringComparison.OrdinalIgnoreCase))
                {
                    return(RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.InvalidRequest, $"The jsonrpc version '{rpcVersion}' is not supported. Supported versions: '2.0'")));
                }

                return(RpcRequestParseResult.Success(id, method !, parameters));
            }
            catch (Exception ex)
            {
                RpcError error;
                if (ex is RpcException rpcException)
                {
                    error = rpcException.ToRpcError(this.serverConfig.Value.ShowServerExceptions);
                }
                else
                {
                    error = new RpcError(RpcErrorCode.ParseError, "Failed to parse request.", ex);
                }
                return(RpcRequestParseResult.Fail(id, error));
            }
        }