DefaultRpcParser.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. using JsonRPC4.Common;
  2. using JsonRPC4.Router.Abstractions;
  3. using JsonRPC4.Router.Utilities;
  4. using Microsoft.Extensions.Logging;
  5. using Microsoft.Extensions.Options;
  6. using System;
  7. using System.Buffers;
  8. using System.Collections.Generic;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Text.Json;
  12. using System.Threading.Tasks;
  13. namespace JsonRPC4.Router.Defaults
  14. {
  15. public class DefaultRpcParser : IRpcParser
  16. {
  17. private ILogger<DefaultRpcParser> logger
  18. {
  19. get;
  20. }
  21. private IOptions<RpcServerConfiguration> serverConfig
  22. {
  23. get;
  24. }
  25. public DefaultRpcParser(ILogger<DefaultRpcParser> logger, IOptions<RpcServerConfiguration> serverConfig)
  26. {
  27. this.logger = logger;
  28. this.serverConfig = serverConfig;
  29. }
  30. public ParsingResult ParseRequests(Stream jsonStream)
  31. {
  32. //IL_0073: Unknown result type (might be due to invalid IL or missing references)
  33. //IL_007a: Unknown result type (might be due to invalid IL or missing references)
  34. //IL_0080: Unknown result type (might be due to invalid IL or missing references)
  35. //IL_0095: Unknown result type (might be due to invalid IL or missing references)
  36. //IL_009a: Unknown result type (might be due to invalid IL or missing references)
  37. //IL_009c: Unknown result type (might be due to invalid IL or missing references)
  38. //IL_009f: Invalid comparison between Unknown and I4
  39. //IL_00a1: Unknown result type (might be due to invalid IL or missing references)
  40. //IL_00a4: Invalid comparison between Unknown and I4
  41. //IL_00b4: Unknown result type (might be due to invalid IL or missing references)
  42. //IL_00e6: Unknown result type (might be due to invalid IL or missing references)
  43. //IL_0104: Unknown result type (might be due to invalid IL or missing references)
  44. //IL_010a: Invalid comparison between Unknown and I4
  45. logger.ParsingRequests();
  46. List<RpcRequestParseResult> list = null;
  47. if (jsonStream == null || jsonStream.Length < 1)
  48. {
  49. throw new RpcException(RpcErrorCode.InvalidRequest, "Json request was empty");
  50. }
  51. bool isBulkRequest = false;
  52. try
  53. {
  54. if (jsonStream.Length > int.MaxValue)
  55. {
  56. throw new RpcException(RpcErrorCode.ParseError, "Json body is too large to parse.");
  57. }
  58. byte[] array = ArrayPool<byte>.Shared.Rent((int)jsonStream.Length);
  59. try
  60. {
  61. jsonStream.Read(array, 0, (int)jsonStream.Length);
  62. Utf8JsonReader jsonReader = new Utf8JsonReader(array, default(JsonReaderOptions));
  63. if (jsonReader.Read())
  64. {
  65. JsonTokenType tokenType = jsonReader.TokenType;
  66. if ( tokenType != JsonTokenType.StartObject)
  67. {
  68. if ( tokenType != JsonTokenType.StartArray)
  69. {
  70. throw new RpcException(RpcErrorCode.InvalidRequest, "Json request was invalid");
  71. }
  72. isBulkRequest = true;
  73. jsonReader.Read();
  74. list = new List<RpcRequestParseResult>();
  75. while (jsonReader.TokenType !=JsonTokenType.EndObject)
  76. {
  77. RpcRequestParseResult item = ParseResult(ref jsonReader, array);
  78. list.Add(item);
  79. jsonReader.Read();
  80. }
  81. }
  82. else
  83. {
  84. jsonReader.Read();
  85. RpcRequestParseResult item2 = ParseResult(ref jsonReader, array);
  86. list = new List<RpcRequestParseResult>
  87. {
  88. item2
  89. };
  90. }
  91. }
  92. }
  93. finally
  94. {
  95. ArrayPool<byte>.Shared.Return(array, false);
  96. }
  97. }
  98. catch (Exception ex) when (!(ex is RpcException))
  99. {
  100. string message = "Unable to parse json request into an rpc format.";
  101. logger.LogException(ex, message);
  102. throw new RpcException(RpcErrorCode.InvalidRequest, message, ex);
  103. }
  104. if (list == null || !list.Any())
  105. {
  106. throw new RpcException(RpcErrorCode.InvalidRequest, "No rpc json requests found");
  107. }
  108. logger.ParsedRequests(list.Count);
  109. HashSet<RpcId> hashSet = new HashSet<RpcId>();
  110. foreach (RpcRequestParseResult item3 in list.Where((RpcRequestParseResult r) => r.Id.HasValue))
  111. {
  112. if (!hashSet.Add(item3.Id))
  113. {
  114. throw new RpcException(RpcErrorCode.InvalidRequest, "Duplicate ids in batch requests are not allowed");
  115. }
  116. }
  117. return ParsingResult.FromResults(list, isBulkRequest);
  118. }
  119. private RpcRequestParseResult ParseResult(ref Utf8JsonReader jsonReader, Memory<byte> bytes)
  120. {
  121. RpcId id = default(RpcId);
  122. string text = null;
  123. RpcParameters parameters = null;
  124. string text2 = null;
  125. try
  126. {
  127. if (jsonReader.TokenType == JsonTokenType.StartObject)
  128. {
  129. jsonReader.Read();
  130. }
  131. long id2 = default;
  132. while (jsonReader.TokenType != JsonTokenType.EndObject)
  133. {
  134. string @string = jsonReader.GetString();
  135. jsonReader.Read();
  136. switch (@string)
  137. {
  138. case "id":
  139. {
  140. JsonTokenType tokenType = jsonReader.TokenType;
  141. if (tokenType != JsonTokenType.String)
  142. {
  143. if ((int)tokenType != 8)
  144. {
  145. RpcError error = new RpcError(RpcErrorCode.ParseError, "Unable to parse rpc id as a string or an integer");
  146. return RpcRequestParseResult.Fail(id, error);
  147. }
  148. if (!(jsonReader).TryGetInt64(out id2))
  149. {
  150. RpcError error2 = new RpcError(RpcErrorCode.ParseError, "Unable to parse rpc id as an integer");
  151. return RpcRequestParseResult.Fail(id, error2);
  152. }
  153. id = new RpcId(id2);
  154. }
  155. else
  156. {
  157. id = new RpcId(jsonReader.GetString());
  158. }
  159. break;
  160. }
  161. case "jsonrpc":
  162. text2 = jsonReader.GetString();
  163. break;
  164. case "method":
  165. text = jsonReader.GetString();
  166. break;
  167. case "params":
  168. {
  169. JsonTokenType tokenType = jsonReader.TokenType;
  170. RpcParameters rpcParameters;
  171. if ((int)tokenType != 1)
  172. {
  173. if ((int)tokenType != 3)
  174. {
  175. return RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.InvalidRequest, "The request parameter format is invalid."));
  176. }
  177. jsonReader.Read();
  178. List<IRpcParameter> list = new List<IRpcParameter>();
  179. while (jsonReader.TokenType != JsonTokenType.EndArray)
  180. {
  181. IRpcParameter parameter = GetParameter(ref jsonReader, bytes);
  182. list.Add(parameter);
  183. }
  184. rpcParameters = new RpcParameters(list);
  185. }
  186. else
  187. {
  188. jsonReader.Read();
  189. Dictionary<string, IRpcParameter> dictionary = new Dictionary<string, IRpcParameter>();
  190. while (jsonReader.TokenType != JsonTokenType.EndObject)
  191. {
  192. string string2 = jsonReader.GetString();
  193. jsonReader.Read();
  194. IRpcParameter parameter2 = GetParameter(ref jsonReader, bytes);
  195. dictionary.Add(string2, parameter2);
  196. }
  197. rpcParameters = new RpcParameters(dictionary);
  198. }
  199. parameters = rpcParameters;
  200. break;
  201. }
  202. }
  203. jsonReader.Read();
  204. }
  205. if (string.IsNullOrWhiteSpace(text))
  206. {
  207. return RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.InvalidRequest, "The request method is required."));
  208. }
  209. if (string.IsNullOrWhiteSpace(text2))
  210. {
  211. return RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.InvalidRequest, "The jsonrpc version must be specified."));
  212. }
  213. if (!string.Equals(text2, "2.0", StringComparison.OrdinalIgnoreCase))
  214. {
  215. return RpcRequestParseResult.Fail(id, new RpcError(RpcErrorCode.InvalidRequest, "The jsonrpc version '" + text2 + "' is not supported. Supported versions: '2.0'"));
  216. }
  217. return RpcRequestParseResult.Success(id, text, parameters);
  218. }
  219. catch (Exception ex)
  220. {
  221. RpcException ex2 = ex as RpcException;
  222. RpcError error3 = (ex2 == null) ? new RpcError(RpcErrorCode.ParseError, "Failed to parse request.", ex) : ex2.ToRpcError(serverConfig.Value.ShowServerExceptions);
  223. return RpcRequestParseResult.Fail(id, error3);
  224. }
  225. }
  226. private JsonBytesRpcParameter GetParameter(ref Utf8JsonReader jsonReader, Memory<byte> bytes)
  227. {
  228. //IL_0009: Unknown result type (might be due to invalid IL or missing references)
  229. //IL_000e: Unknown result type (might be due to invalid IL or missing references)
  230. //IL_0010: Unknown result type (might be due to invalid IL or missing references)
  231. //IL_0013: Invalid comparison between Unknown and I4
  232. //IL_0015: Unknown result type (might be due to invalid IL or missing references)
  233. //IL_0018: Unknown result type (might be due to invalid IL or missing references)
  234. //IL_0032: Expected I4, but got Unknown
  235. //IL_0053: Unknown result type (might be due to invalid IL or missing references)
  236. //IL_0059: Invalid comparison between Unknown and I4
  237. //IL_008e: Unknown result type (might be due to invalid IL or missing references)
  238. int num = (int)jsonReader.TokenStartIndex;
  239. JsonTokenType tokenType = jsonReader.TokenType;
  240. RpcParameterType type;
  241. if ((int)tokenType != 1)
  242. {
  243. switch (tokenType )
  244. {
  245. case JsonTokenType.Number:
  246. type = RpcParameterType.Number;
  247. break;
  248. case JsonTokenType.Null:
  249. type = RpcParameterType.Null;
  250. break;
  251. case JsonTokenType.String:
  252. type = RpcParameterType.String;
  253. break;
  254. default:
  255. throw new RpcException(RpcErrorCode.ParseError, "Invalid json");
  256. }
  257. }
  258. else
  259. {
  260. type = RpcParameterType.Object;
  261. int currentDepth = jsonReader.CurrentDepth;
  262. while (jsonReader.TokenType != JsonTokenType.EndObject || jsonReader.CurrentDepth != currentDepth)
  263. {
  264. jsonReader.Read();
  265. }
  266. }
  267. int num2 = (int)jsonReader.BytesConsumed - num;
  268. jsonReader.Read();
  269. return new JsonBytesRpcParameter(type, bytes.Slice(num, num2), serverConfig.Value?.JsonSerializerSettings);
  270. }
  271. }
  272. }