using JsonRPC4.Common; using JsonRPC4.Router.Abstractions; using JsonRPC4.Router.Utilities; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; using System.Buffers; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.Json; using System.Threading.Tasks; namespace JsonRPC4.Router.Defaults { public class DefaultRpcParser : IRpcParser { private ILogger logger { get; } private IOptions serverConfig { get; } public DefaultRpcParser(ILogger logger, IOptions serverConfig) { this.logger = logger; this.serverConfig = serverConfig; } public ParsingResult ParseRequests(Stream jsonStream) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Invalid comparison between Unknown and I4 //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Invalid comparison between Unknown and I4 //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Invalid comparison between Unknown and I4 logger.ParsingRequests(); List list = 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[] array = ArrayPool.Shared.Rent((int)jsonStream.Length); try { jsonStream.Read(array, 0, (int)jsonStream.Length); Utf8JsonReader jsonReader = new Utf8JsonReader(array, default(JsonReaderOptions)); if (jsonReader.Read()) { JsonTokenType tokenType = jsonReader.TokenType; if ( tokenType != JsonTokenType.StartObject) { if ( tokenType != JsonTokenType.StartArray) { throw new RpcException(RpcErrorCode.InvalidRequest, "Json request was invalid"); } isBulkRequest = true; jsonReader.Read(); list = new List(); while (jsonReader.TokenType !=JsonTokenType.EndObject) { RpcRequestParseResult item = ParseResult(ref jsonReader, array); list.Add(item); jsonReader.Read(); } } else { jsonReader.Read(); RpcRequestParseResult item2 = ParseResult(ref jsonReader, array); list = new List { item2 }; } } } finally { ArrayPool.Shared.Return(array, false); } } catch (Exception ex) when (!(ex is RpcException)) { string message = "Unable to parse json request into an rpc format."; logger.LogException(ex, message); throw new RpcException(RpcErrorCode.InvalidRequest, message, ex); } if (list == null || !list.Any()) { throw new RpcException(RpcErrorCode.InvalidRequest, "No rpc json requests found"); } logger.ParsedRequests(list.Count); HashSet hashSet = new HashSet(); foreach (RpcRequestParseResult item3 in list.Where((RpcRequestParseResult r) => r.Id.HasValue)) { if (!hashSet.Add(item3.Id)) { throw new RpcException(RpcErrorCode.InvalidRequest, "Duplicate ids in batch requests are not allowed"); } } return ParsingResult.FromResults(list, isBulkRequest); } private RpcRequestParseResult ParseResult(ref Utf8JsonReader jsonReader, Memory bytes) { RpcId id = default(RpcId); string text = null; RpcParameters parameters = null; string text2 = null; try { if (jsonReader.TokenType == JsonTokenType.StartObject) { jsonReader.Read(); } long id2 = default; while (jsonReader.TokenType != JsonTokenType.EndObject) { string @string = jsonReader.GetString(); jsonReader.Read(); switch (@string) { case "id": { JsonTokenType tokenType = jsonReader.TokenType; if (tokenType != JsonTokenType.String) { if ((int)tokenType != 8) { RpcError error = new RpcError(RpcErrorCode.ParseError, "Unable to parse rpc id as a string or an integer"); return RpcRequestParseResult.Fail(id, error); } if (!(jsonReader).TryGetInt64(out id2)) { RpcError error2 = new RpcError(RpcErrorCode.ParseError, "Unable to parse rpc id as an integer"); return RpcRequestParseResult.Fail(id, error2); } id = new RpcId(id2); } else { id = new RpcId(jsonReader.GetString()); } break; } case "jsonrpc": text2 = jsonReader.GetString(); break; case "method": text = jsonReader.GetString(); break; case "params": { JsonTokenType tokenType = jsonReader.TokenType; RpcParameters rpcParameters; if ((int)tokenType != 1) { if ((int)tokenType != 3) { return RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.InvalidRequest, "The request parameter format is invalid.")); } jsonReader.Read(); List list = new List(); while (jsonReader.TokenType != JsonTokenType.EndArray) { IRpcParameter parameter = GetParameter(ref jsonReader, bytes); list.Add(parameter); } rpcParameters = new RpcParameters(list); } else { jsonReader.Read(); Dictionary dictionary = new Dictionary(); while (jsonReader.TokenType != JsonTokenType.EndObject) { string string2 = jsonReader.GetString(); jsonReader.Read(); IRpcParameter parameter2 = GetParameter(ref jsonReader, bytes); dictionary.Add(string2, parameter2); } rpcParameters = new RpcParameters(dictionary); } parameters = rpcParameters; break; } } jsonReader.Read(); } if (string.IsNullOrWhiteSpace(text)) { return RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.InvalidRequest, "The request method is required.")); } if (string.IsNullOrWhiteSpace(text2)) { return RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.InvalidRequest, "The jsonrpc version must be specified.")); } if (!string.Equals(text2, "2.0", StringComparison.OrdinalIgnoreCase)) { return RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.InvalidRequest, "The jsonrpc version '" + text2 + "' is not supported. Supported versions: '2.0'")); } return RpcRequestParseResult.Success(id, text, parameters); } catch (Exception ex) { RpcException ex2 = ex as RpcException; RpcError error3 = (ex2 == null) ? new RpcError(RpcErrorCode.ParseError, "Failed to parse request.", ex) : ex2.ToRpcError(serverConfig.Value.ShowServerExceptions); return RpcRequestParseResult.Fail(id, error3); } } private JsonBytesRpcParameter GetParameter(ref Utf8JsonReader jsonReader, Memory bytes) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected I4, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Invalid comparison between Unknown and I4 //IL_008e: Unknown result type (might be due to invalid IL or missing references) int num = (int)jsonReader.TokenStartIndex; JsonTokenType tokenType = jsonReader.TokenType; RpcParameterType type; if ((int)tokenType != 1) { switch (tokenType ) { case JsonTokenType.Number: type = RpcParameterType.Number; break; case JsonTokenType.Null: type = RpcParameterType.Null; break; case JsonTokenType.String: type = RpcParameterType.String; break; default: throw new RpcException(RpcErrorCode.ParseError, "Invalid json"); } } else { type = RpcParameterType.Object; int currentDepth = jsonReader.CurrentDepth; while (jsonReader.TokenType != JsonTokenType.EndObject || jsonReader.CurrentDepth != currentDepth) { jsonReader.Read(); } } int num2 = (int)jsonReader.BytesConsumed - num; jsonReader.Read(); return new JsonBytesRpcParameter(type, bytes.Slice(num, num2), serverConfig.Value?.JsonSerializerSettings); } } }