/// <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)); }
/// <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)); }