Exemple #1
0
        /// <summary>
        /// Parses all the requests from the json in the request
        /// </summary>
        /// <param name="jsonString">Json from the http request</param>
        /// <param name="isBulkRequest">If true, the request is a bulk request (even if there is only one)</param>
        /// <returns>List of Rpc requests that were parsed from the json</returns>
        public ParsingResult ParseRequests(Stream jsonStream)
        {
            this.logger.ParsingRequests();
            List <RpcRequestParseResult>?rpcRequests = null;

            if (jsonStream == null || jsonStream.Length < 1)
            {
                throw new RpcException(RpcErrorCode.InvalidRequest, "Json request was empty");
            }
            bool isBulkRequest = false;

            try
            {
                if (jsonStream.Length > int.MaxValue)
                {
                    throw new RpcException(RpcErrorCode.ParseError, "Json body is too large to parse.");
                }
                var jsonDocument = JsonDocument.Parse(jsonStream);
                switch (jsonDocument.RootElement.ValueKind)
                {
                case JsonValueKind.Object:
                    RpcRequestParseResult result = this.ParseResult(jsonDocument.RootElement.EnumerateObject());
                    rpcRequests = new List <RpcRequestParseResult> {
                        result
                    };
                    break;

                case JsonValueKind.Array:
                    isBulkRequest = true;
                    rpcRequests   = new List <RpcRequestParseResult>();
                    foreach (JsonElement element in jsonDocument.RootElement.EnumerateArray())
                    {
                        RpcRequestParseResult r = this.ParseResult(element.EnumerateObject());
                        rpcRequests.Add(r);
                    }
                    break;

                default:
                    throw new RpcException(RpcErrorCode.InvalidRequest, "Json request was invalid");
                }
            }
            catch (Exception ex) when(!(ex is RpcException))
            {
                string errorMessage = "Unable to parse json request into an rpc format.";

                this.logger.LogException(ex, errorMessage);
                throw new RpcException(RpcErrorCode.InvalidRequest, errorMessage, ex);
            }

            if (rpcRequests == null || !rpcRequests.Any())
            {
                throw new RpcException(RpcErrorCode.InvalidRequest, "No rpc json requests found");
            }
            this.logger.ParsedRequests(rpcRequests.Count);
            var uniqueIds = new HashSet <RpcId>();

            foreach (RpcRequestParseResult result in rpcRequests.Where(r => r.Id.HasValue))
            {
                bool unique = uniqueIds.Add(result.Id);
                if (!unique)
                {
                    throw new RpcException(RpcErrorCode.InvalidRequest, "Duplicate ids in batch requests are not allowed");
                }
            }
            return(ParsingResult.FromResults(rpcRequests, isBulkRequest));
        }
Exemple #2
0
        /// <summary>
        /// Parses all the requests from the json in the request
        /// </summary>
        /// <param name="jsonString">Json from the http request</param>
        /// <param name="isBulkRequest">If true, the request is a bulk request (even if there is only one)</param>
        /// <returns>List of Rpc requests that were parsed from the json</returns>
        public ParsingResult ParseRequests(Stream jsonStream)
        {
            this.logger.ParsingRequests();
            List <RpcRequestParseResult>?rpcRequests = null;

            if (jsonStream == null || jsonStream.Length < 1)
            {
                throw new RpcException(RpcErrorCode.InvalidRequest, "Json request was empty");
            }
            bool isBulkRequest = false;

            try
            {
                if (jsonStream.Length > int.MaxValue)
                {
                    throw new RpcException(RpcErrorCode.ParseError, "Json body is too large to parse.");
                }
                byte[] jsonBytes = ArrayPool <byte> .Shared.Rent((int)jsonStream.Length);

                try
                {
                    jsonStream.Read(jsonBytes, 0, (int)jsonStream.Length);
                    var jsonReader = new Utf8JsonReader(jsonBytes);
                    if (jsonReader.Read())
                    {
                        switch (jsonReader.TokenType)
                        {
                        case JsonTokenType.StartObject:
                            jsonReader.Read();
                            RpcRequestParseResult result = this.ParseResult(ref jsonReader, jsonBytes);
                            rpcRequests = new List <RpcRequestParseResult> {
                                result
                            };
                            break;

                        case JsonTokenType.StartArray:
                            isBulkRequest = true;
                            jsonReader.Read();
                            rpcRequests = new List <RpcRequestParseResult>();
                            while (jsonReader.TokenType != JsonTokenType.EndArray)
                            {
                                RpcRequestParseResult r = this.ParseResult(ref jsonReader, jsonBytes);
                                rpcRequests.Add(r);
                                jsonReader.Read();
                            }
                            break;

                        default:
                            throw new RpcException(RpcErrorCode.InvalidRequest, "Json request was invalid");
                        }
                    }
                }
                finally
                {
                    ArrayPool <byte> .Shared.Return(jsonBytes, clearArray : false);
                }
            }
            catch (Exception ex) when(!(ex is RpcException))
            {
                string errorMessage = "Unable to parse json request into an rpc format.";

                this.logger.LogException(ex, errorMessage);
                throw new RpcException(RpcErrorCode.InvalidRequest, errorMessage, ex);
            }

            if (rpcRequests == null || !rpcRequests.Any())
            {
                throw new RpcException(RpcErrorCode.InvalidRequest, "No rpc json requests found");
            }
            this.logger.ParsedRequests(rpcRequests.Count);
            var uniqueIds = new HashSet <RpcId>();

            foreach (RpcRequestParseResult result in rpcRequests.Where(r => r.Id.HasValue))
            {
                bool unique = uniqueIds.Add(result.Id);
                if (!unique)
                {
                    throw new RpcException(RpcErrorCode.InvalidRequest, "Duplicate ids in batch requests are not allowed");
                }
            }
            return(ParsingResult.FromResults(rpcRequests, isBulkRequest));
        }
        /// <summary>
        /// Parses all the requests from the json in the request
        /// </summary>
        /// <param name="jsonString">Json from the http request</param>
        /// <param name="isBulkRequest">If true, the request is a bulk request (even if there is only one)</param>
        /// <returns>List of Rpc requests that were parsed from the json</returns>
        public ParsingResult ParseRequests(string jsonString)
        {
            this.logger?.LogDebug($"Attempting to parse Rpc request from the json string '{jsonString}'");
            List <RpcRequestParseResult> rpcRequests;

            if (string.IsNullOrWhiteSpace(jsonString))
            {
                throw new RpcException(RpcErrorCode.InvalidRequest, "Json request was empty");
            }
            bool isBulkRequest;

            try
            {
                using (JsonReader jsonReader = new JsonTextReader(new StringReader(jsonString)))
                {
                    //Fixes the date parsing issue https://github.com/JamesNK/Newtonsoft.Json/issues/862
                    jsonReader.DateParseHandling = DateParseHandling.None;

                    JToken token = JToken.Load(jsonReader);
                    switch (token.Type)
                    {
                    case JTokenType.Array:
                        isBulkRequest = true;
                        rpcRequests   = ((JArray)token).Select(this.DeserializeRequest).ToList();
                        break;

                    case JTokenType.Object:
                        isBulkRequest = false;
                        RpcRequestParseResult result = this.DeserializeRequest(token);
                        rpcRequests = new List <RpcRequestParseResult> {
                            result
                        };
                        break;

                    default:
                        throw new RpcException(RpcErrorCode.ParseError, "Json body is not an array or an object.");
                    }
                }
            }
            catch (Exception ex) when(!(ex is RpcException))
            {
                string errorMessage = "Unable to parse json request into an rpc format.";

                this.logger?.LogException(ex, errorMessage);
                throw new RpcException(RpcErrorCode.InvalidRequest, errorMessage, ex);
            }

            if (rpcRequests == null || !rpcRequests.Any())
            {
                throw new RpcException(RpcErrorCode.InvalidRequest, "No rpc json requests found");
            }
            this.logger?.LogDebug($"Successfully parsed {rpcRequests.Count} Rpc request(s)");
            var uniqueIds = new HashSet <RpcId>();

            foreach (RpcRequestParseResult result in rpcRequests.Where(r => r.Request != null && r.Request.Id.HasValue))
            {
                bool unique = uniqueIds.Add(result.Request.Id);
                if (!unique)
                {
                    throw new RpcException(RpcErrorCode.InvalidRequest, "Duplicate ids in batch requests are not allowed");
                }
            }
            return(ParsingResult.FromResults(rpcRequests, isBulkRequest));
        }