public IObservable <JsonResponse <T> > Invoke <T>(string method, object[] args) { var req = new AustinHarris.JsonRpc.JsonRequest() { Method = method, Params = args }; return(InvokeRequest <T>(req)); }
public IObservable <JsonResponse <T> > InvokeSingleArgument <T>(string method, object arg) { var req = new AustinHarris.JsonRpc.JsonRequest() { Method = method, Params = new object[] { arg } }; return(InvokeRequest <T>(req)); }
public IObservable <JsonResponse <T> > InvokeWithScheduler <T>(string method, object[] args, IScheduler scheduler) { var req = new AustinHarris.JsonRpc.JsonRequest() { Method = method, Params = args }; return(InvokeRequestWithScheduler <T>(req, scheduler)); }
private JsonRpcException PreProcess(JsonRequest rpc, object context) { // Useful for logging or authentication using the context. if(!string.Equals(rpc.Method, "RequiresCredentials",StringComparison.CurrentCultureIgnoreCase)) return null; // If this is using the ASP.Net handler then the context will contain the httpRequest // you could use that for cookies or IP authentication. // Here we will just check that the first parameter is a magic Key // DO NOT do this type of thing in production code. You would be better just checking the parameter inside the JsonRpcMethod. var j = rpc.Params as Newtonsoft.Json.Linq.JArray; if (j == null || j[0] == null || j[0].Type != Newtonsoft.Json.Linq.JTokenType.String || !string.Equals(j[0].ToString(), "GoodPassword", StringComparison.CurrentCultureIgnoreCase) ) return new JsonRpcException(-2, "This exception was thrown using: JsonRpcTest.Global.PreProcess, Not Authenticated", null); return null; }
/// <summary> /// Sets a new difficulty to the miner and sends it. /// </summary> public void SetDifficulty(float difficulty) { if (Difficulty == difficulty) // if new difficulty is the same with current one, return; // just skip. PreviousDifficulty = Difficulty; // store the previous difficulty (so we can still accept shares targeted for last difficulty when vardiff sets a new difficulty). Difficulty = difficulty; var notification = new JsonRequest { Id = null, Method = "mining.set_difficulty", Params = new List<object>{ Difficulty } }; Send(notification); //send the difficulty update message. _storageLayer.UpdateDifficulty(this); // store the new difficulty within persistance layer. }
private void Send(JsonRequest request) { var json = JsonConvert.SerializeObject(request) + "\n"; var data = Encoding.UTF8.GetBytes(json); Connection.Send(data); _packetLogger.Verbose("tx: {0}", data.ToEncodedString().PrettifyJson()); }
/// <summary> /// Sends a mining-job to miner. /// </summary> public void SendJob(IJob job) { var notification = new JsonRequest { Id = null, Method = "mining.notify", Params = job }; Send(notification); }
/// <summary> /// Sends message of the day to miner. /// </summary> public void SendMessage(string message) { var notification = new JsonRequest { Id = null, Method = "client.show_message", Params = new List<object> { message } }; Send(notification); }
public void TestJsonpWithHttpGet() { string method = "internal.echo"; string input = "Echo this sucka"; string id = "1"; string callbackName = "myCallback"; object[] parameters = new object[1]; parameters[0] = input; JsonRequest jsonParameters = new JsonRequest() { Method = method, Params = parameters, Id = id }; var serailaizedParameters = Newtonsoft.Json.JsonConvert.SerializeObject(jsonParameters); string uri = string.Format("{0}?jsonrpc={1}&callback={2}", remoteUri, serailaizedParameters, callbackName, id); WebRequest request = WebRequest.Create(uri); WebResponse response = request.GetResponse(); StreamReader reader = new StreamReader(response.GetResponseStream()); var regexPattern = callbackName + @"\({.*}\)"; var result = reader.ReadToEnd().Trim(); Assert.IsTrue(Regex.IsMatch(result, regexPattern)); }
public void TestJsonPWithHttpPost() { string method = "internal.echo"; string input = "Echo this sucka"; string id = "1"; string callbackName = "myCallback"; object[] parameters = new object[1]; parameters[0] = input; JsonRequest jsonParameters = new JsonRequest() { Method = method, Params = parameters, Id = id }; var serailaizedParameters = Newtonsoft.Json.JsonConvert.SerializeObject(jsonParameters); var postData = string.Format("jsonrpc={0}&callback={1}", serailaizedParameters, callbackName); WebRequest request = WebRequest.Create(remoteUri); request.ContentType = "application/x-www-form-urlencoded"; request.Method = "POST"; byte[] bytes = System.Text.Encoding.ASCII.GetBytes(postData); request.ContentLength = bytes.Length; using (Stream stream = request.GetRequestStream()) { stream.Write(bytes, 0, bytes.Length); stream.Close(); } WebResponse response = request.GetResponse(); StreamReader reader = new StreamReader(response.GetResponseStream()); //myCallback({"jsonrpc":"2.0","result":"Echo this sucka","id":"1"}) var regexPattern = callbackName + @"\({.*}\)"; var result = reader.ReadToEnd().Trim(); Assert.IsTrue(Regex.IsMatch(result, regexPattern)); }
private JsonRpcException ProcessException(JsonRequest req,JsonRpcException ex) { if(externalErrorHandler!=null) return externalErrorHandler(req,ex); return ex; }
/// <summary> /// Sends difficulty to the miner. /// </summary> public void SendDifficulty() { var notification = new JsonRequest { Id = null, Method = "mining.set_difficulty", Params = new Difficulty(Difficulty) }; var json = JsonConvert.SerializeObject(notification) + "\n"; var data = Encoding.UTF8.GetBytes(json); Connection.Send(data); _logger.Verbose("tx: {0}", data.ToEncodedString().PrettifyJson()); }
/// <summary> /// Sends a mining-job to miner. /// </summary> public void SendJob(JobNotification jobNotification) { var notification = new JsonRequest { Id = null, Method = "mining.notify", Params = jobNotification }; //Params = new JobNotification() //{ // Id = "2b50", // PreviousBlockHash = "8f0472e229d7f803642efac67a3daeabbe9bda7ac7872ea19e3978cf3e65261d", // CoinbaseInitial = "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff2703c33a07062f503253482f047028a25208", // CoinbaseFinal = "0d2f7374726174756d506f6f6c2f0000000001fe7aaa2a010000001976a9145b771921a9b47ee8104da7e4710b5f633d95fa7388ac00000000", // MerkleBranches = new List<object> // { // "795ec58b7ebf9522ad15b76207c8f40e569cfd478c2e2c30bfa06c8a6d24609d", // "e76544a1b9d7550280c49bf965d5882c65f8cd4b9711202cc9bd311f76b438ac", // "01acd5a2a3142d735e4847a5b512aef35f22f67eb2d7be1f4dcdfca3c4031a43", // "4c561433d42406ca777fb1aa730a6b96317ca68c2341b5f0f52afc2ae1b6235d" // }, // BlockVersion = "00000002", // NetworkDifficulty = "1b1d88f6", // nTime = "52a22871", // CleanJobs = false //} var json = JsonConvert.SerializeObject(notification) + "\n"; var data = Encoding.UTF8.GetBytes(json); this.Connection.Send(data); Log.Verbose("RPC-client send:\n{0}", data.ToEncodedString()); }
private JsonRpcException PreProcess(JsonRequest request, object context) { return(externalPreProcessingHandler?.Invoke(request, context)); }
protected JsonResponse handleJsonRpcRequest(String method, Object[] parameters, string uniqueID) { try { JsonRequest request = new JsonRequest { Method = method, Params = parameters, Id = uniqueID }; JArray jsonParams = request.Params as JArray; JsonResponse jsonResponse = null; // create a JSON string from the request object String requestString = JsonConvert.SerializeObject(request, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Serialize }); Trace.TraceInformation("sending request: " + requestString); // attempting to send the request via the writer to // the JSON-RPC server might throw an IOException if (writer != null) { writer.Write(requestString); // flush the stream to make sure the request is sent via the socket writer.Flush(); } // try to receive a response via the reader if (reader != null) { var response = jsonSerializer.Deserialize(reader, typeof(JsonResponse)); // check whether a response has been received if (response != null) { jsonResponse = (JsonResponse)response; // (re-)serialize the response for informational purposes String responseString = JsonConvert.SerializeObject(jsonResponse); Trace.TraceInformation("received response: " + responseString); } else { // connection to JSON-RPC server is lost Trace.TraceInformation("server connection dropped"); establishSocketConnection(); } } else { // connection to JSON-RPC server is lost Trace.TraceInformation("server connection dropped"); establishSocketConnection(); } return jsonResponse; } catch (Exception ex) { Trace.TraceInformation("There was an error while handling a JSONRCP request, was the server shutting down? Error reads: " + ex.Message); return null; } }
/// <summary> /// Sends a mining-job to miner. /// </summary> public void SendJob(IJob job) { var notification = new JsonRequest { Id = null, Method = "mining.notify", Params = job }; var json = JsonConvert.SerializeObject(notification) + "\n"; var data = Encoding.UTF8.GetBytes(json); Connection.Send(data); Log.ForContext<StratumMiner>().Verbose("Send:\n{0}", data.ToEncodedString().PrettifyJson()); }
private AustinHarris.JsonRpc.JsonRpcException OnJsonRpcException(AustinHarris.JsonRpc.JsonRequest rpc, AustinHarris.JsonRpc.JsonRpcException ex) { return(ex); }
/// <summary> /// Invokes a method to handle a JsonRpc request. /// </summary> /// <param name="Rpc">JsonRpc Request to be processed</param> /// <param name="RpcContext">Optional context that will be available from within the jsonRpcMethod.</param> /// <returns></returns> public JsonResponse Handle(JsonRequest Rpc, Object RpcContext = null) { AddRpcContext(RpcContext); var preProcessingException = PreProcess(Rpc, RpcContext); if (preProcessingException != null) { JsonResponse response = new JsonResponse() { Error = preProcessingException, Id = Rpc.Id }; //callback is called - if it is empty then nothing will be done //return response always- if callback is empty or not return(PostProcess(Rpc, response, RpcContext)); } SMDService metadata = null; Delegate handle = null; if (this.MetaData.Services.TryGetValue(Rpc.Method, out metadata)) { handle = metadata.dele; } else if (metadata == null) { JsonResponse response = new JsonResponse() { Result = null, Error = new JsonRpcException(-32601, "Method not found", "The method does not exist / is not available."), Id = Rpc.Id }; return(PostProcess(Rpc, response, RpcContext)); } object[] parameters = null; bool expectsRefException = false; var metaDataParamCount = metadata.parameters.Count(x => x != null); var loopCt = 0; var getCount = Rpc.Params as ICollection; if (getCount != null) { loopCt = getCount.Count; } var paramCount = loopCt; if (paramCount == metaDataParamCount - 1 && metadata.parameters[metaDataParamCount - 1].ObjectType.Name.Equals(Name_of_JSONRPCEXCEPTION)) { paramCount++; expectsRefException = true; } parameters = new object[paramCount]; if (Rpc.Params is Newtonsoft.Json.Linq.JArray) { var jarr = ((Newtonsoft.Json.Linq.JArray)Rpc.Params); for (int i = 0; i < loopCt && i < metadata.parameters.Length; i++) { parameters[i] = CleanUpParameter(jarr[i], metadata.parameters[i]); } } else if (Rpc.Params is Newtonsoft.Json.Linq.JObject) { var asDict = Rpc.Params as IDictionary <string, Newtonsoft.Json.Linq.JToken>; for (int i = 0; i < loopCt && i < metadata.parameters.Length; i++) { if (asDict.ContainsKey(metadata.parameters[i].Name) == true) { parameters[i] = CleanUpParameter(asDict[metadata.parameters[i].Name], metadata.parameters[i]); continue; } else { var foundDefault = metadata.defaultValues .FirstOrDefault(defaul => defaul.Name == metadata.parameters[i].Name); if (foundDefault != null) { parameters[i] = foundDefault.Value; continue; } JsonResponse response = new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32602, "Invalid params", string.Format("Named parameter '{0}' was not present.", metadata.parameters[i].Name) )), Id = Rpc.Id }; return(PostProcess(Rpc, response, RpcContext)); } } } // Optional Parameter support // check if we still miss parameters compared to metadata which may include optional parameters. // if the rpc-call didn't supply a value for an optional parameter, we should be assinging the default value of it. if (parameters.Length < metaDataParamCount && metadata.defaultValues.Length > 0) // rpc call didn't set values for all optional parameters, so we need to assign the default values for them. { var suppliedParamsCount = parameters.Length; // the index we should start storing default values of optional parameters. var missingParamsCount = metaDataParamCount - parameters.Length; // the amount of optional parameters without a value set by rpc-call. Array.Resize(ref parameters, parameters.Length + missingParamsCount); // resize the array to include all optional parameters. for (int paramIndex = parameters.Length - 1, defaultIndex = metadata.defaultValues.Length - 1; // fill missing parameters from the back paramIndex >= suppliedParamsCount && defaultIndex >= 0; // to don't overwrite supplied ones. paramIndex--, defaultIndex--) { parameters[paramIndex] = metadata.defaultValues[defaultIndex].Value; } if (missingParamsCount > metadata.defaultValues.Length) { JsonResponse response = new JsonResponse { Error = ProcessException(Rpc, new JsonRpcException(-32602, "Invalid params", string.Format( "Number of default parameters {0} not sufficient to fill all missing parameters {1}", metadata.defaultValues.Length, missingParamsCount) )), Id = Rpc.Id }; return(PostProcess(Rpc, response, RpcContext)); } } if (parameters.Length != metaDataParamCount) { JsonResponse response = new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32602, "Invalid params", string.Format("Expecting {0} parameters, and received {1}", metadata.parameters.Length, parameters.Length) )), Id = Rpc.Id }; return(PostProcess(Rpc, response, RpcContext)); } try { var results = handle.DynamicInvoke(parameters); var last = parameters.LastOrDefault(); var contextException = RpcGetAndRemoveRpcException(); JsonResponse response = null; if (contextException != null) { response = new JsonResponse() { Error = ProcessException(Rpc, contextException), Id = Rpc.Id }; } else if (expectsRefException && last != null && last is JsonRpcException) { response = new JsonResponse() { Error = ProcessException(Rpc, last as JsonRpcException), Id = Rpc.Id }; } else { response = new JsonResponse() { Result = results }; } return(PostProcess(Rpc, response, RpcContext)); } catch (Exception ex) { JsonResponse response; if (ex is TargetParameterCountException) { response = new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32602, "Invalid params", ex)) }; return(PostProcess(Rpc, response, RpcContext)); } // We really dont care about the TargetInvocationException, just pass on the inner exception if (ex is JsonRpcException) { response = new JsonResponse() { Error = ProcessException(Rpc, ex as JsonRpcException) }; return(PostProcess(Rpc, response, RpcContext)); } if (ex.InnerException != null && ex.InnerException is JsonRpcException) { response = new JsonResponse() { Error = ProcessException(Rpc, ex.InnerException as JsonRpcException) }; return(PostProcess(Rpc, response, RpcContext)); } else if (ex.InnerException != null) { response = new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32603, "Internal Error", ex.InnerException)) }; return(PostProcess(Rpc, response, RpcContext)); } response = new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32603, "Internal Error", ex)) }; return(PostProcess(Rpc, response, RpcContext)); } finally { RemoveRpcContext(); } }
private JsonResponse PostProcess(Action<JsonResponse> callback, JsonRequest request, JsonResponse response, object context) { if (externalPostProcessingHandler != null) { try { JsonRpcException exception = externalPostProcessingHandler(request, response, context); if (exception != null) { response = new JsonResponse() { Error = exception }; } } catch (Exception ex) { response = new JsonResponse() { Error = ProcessException(request, new JsonRpcException(-32603, "Internal Error", ex)) }; } } if (callback != null) callback.Invoke(response); return response; }
public JsonRpcException PreProcess(JsonRequest rpc, object context) { run++; this.rpc = rpc; this.context = context; return null; }
/// <summary> /// Invokes a method to handle a JsonRpc request. /// </summary> /// <param name="Rpc">JsonRpc Request to be processed</param> /// <param name="RpcContext">Optional context that will be available from within the jsonRpcMethod.</param> /// <returns></returns> public JsonResponse Handle(JsonRequest Rpc, Object RpcContext = null, Action<JsonResponse> callback = null) { //empty delegate declaration if callback is not provided if (null == callback) { callback = delegate(JsonResponse a) { }; } AddRpcContext(RpcContext); var preProcessingException = PreProcess(Rpc, RpcContext); if (preProcessingException != null) { JsonResponse response = new JsonResponse() { Error = preProcessingException, Id = Rpc.Id }; //callback is called - if it is empty then nothing will be done callback.Invoke(response); //return response always- if callback is empty or not return response; } SMDService metadata = null; Delegate handle = null; var haveDelegate = this.Handlers.TryGetValue(Rpc.Method, out handle); var haveMetadata = this.MetaData.Services.TryGetValue(Rpc.Method, out metadata); if (haveDelegate == false || haveMetadata == false || metadata == null || handle == null) { JsonResponse response = new JsonResponse() { Result = null, Error = new JsonRpcException(-32601, "Method not found", "The method does not exist / is not available."), Id = Rpc.Id }; callback.Invoke(response); return response; } bool isJObject = Rpc.Params is Newtonsoft.Json.Linq.JObject; bool isJArray = Rpc.Params is Newtonsoft.Json.Linq.JArray; object[] parameters = null; bool expectsRefException = false; var metaDataParamCount = metadata.parameters.Count(x => x != null); var getCount = Rpc.Params as ICollection; var loopCt = 0; if (getCount != null) { loopCt = getCount.Count; } var paramCount = loopCt; if (paramCount == metaDataParamCount - 1 && metadata.parameters[metaDataParamCount - 1].ObjectType.Name.Contains(typeof(JsonRpcException).Name)) { paramCount++; expectsRefException = true; } parameters = new object[paramCount]; if (isJArray) { var jarr = ((Newtonsoft.Json.Linq.JArray)Rpc.Params); //var loopCt = jarr.Count; //var pCount = loopCt; //if (pCount == metaDataParamCount - 1 && metadata.parameters[metaDataParamCount].GetType() == typeof(JsonRpcException)) // pCount++; //parameters = new object[pCount]; for (int i = 0; i < loopCt; i++) { parameters[i] = CleanUpParameter(jarr[i], metadata.parameters[i]); } } else if (isJObject) { var jo = Rpc.Params as Newtonsoft.Json.Linq.JObject; //var loopCt = jo.Count; //var pCount = loopCt; //if (pCount == metaDataParamCount - 1 && metadata.parameters[metaDataParamCount].GetType() == typeof(JsonRpcException)) // pCount++; //parameters = new object[pCount]; var asDict = jo as IDictionary<string, Newtonsoft.Json.Linq.JToken>; for (int i = 0; i < loopCt; i++) { if (asDict.ContainsKey(metadata.parameters[i].Name) == false) { JsonResponse response = new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32602, "Invalid params", string.Format("Named parameter '{0}' was not present.", metadata.parameters[i].Name) )), Id = Rpc.Id }; callback.Invoke(response); return response; } parameters[i] = CleanUpParameter(jo[metadata.parameters[i].Name], metadata.parameters[i]); } } // Optional Parameter support // check if we still miss parameters compared to metadata which may include optional parameters. // if the rpc-call didn't supply a value for an optional parameter, we should be assinging the default value of it. if (parameters.Length < metaDataParamCount && metadata.defaultValues.Length > 0) // rpc call didn't set values for all optional parameters, so we need to assign the default values for them. { var suppliedParamsCount = parameters.Length; // the index we should start storing default values of optional parameters. var missingParamsCount = metaDataParamCount - parameters.Length; // the amount of optional parameters without a value set by rpc-call. Array.Resize(ref parameters, parameters.Length + missingParamsCount); // resize the array to include all optional parameters. for (int paramIndex = parameters.Length - 1, defaultIndex = metadata.defaultValues.Length - 1; // fill missing parameters from the back paramIndex >= suppliedParamsCount && defaultIndex >= 0; // to don't overwrite supplied ones. paramIndex--, defaultIndex--) { parameters[paramIndex] = metadata.defaultValues[defaultIndex].Value; } if (missingParamsCount > metadata.defaultValues.Length) { JsonResponse response = new JsonResponse { Error = ProcessException(Rpc, new JsonRpcException(-32602, "Invalid params", string.Format( "Number of default parameters {0} not sufficient to fill all missing parameters {1}", metadata.defaultValues.Length, missingParamsCount) )), Id = Rpc.Id }; callback.Invoke(response); return response; } } if (parameters.Length != metaDataParamCount) { JsonResponse response = new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32602, "Invalid params", string.Format("Expecting {0} parameters, and received {1}", metadata.parameters.Length, parameters.Length) )), Id = Rpc.Id }; callback.Invoke(response); return response; } try { //callback is stored to thread's local storage in order to get it directly from concrete JsonRpcService method implementation //where callback is just returned from method Thread.SetData(Thread.GetNamedDataSlot(THREAD_CALLBACK_SLOT_NAME), callback); var results = handle.DynamicInvoke(parameters); var last = parameters.LastOrDefault(); JsonRpcException contextException; if (Task.CurrentId.HasValue && RpcExceptions.TryRemove(Task.CurrentId.Value, out contextException)) { JsonResponse response = new JsonResponse() { Error = ProcessException(Rpc, contextException), Id = Rpc.Id }; callback.Invoke(response); return response; } if (expectsRefException && last != null && last is JsonRpcException) { JsonResponse response = new JsonResponse() { Error = ProcessException(Rpc, last as JsonRpcException), Id = Rpc.Id }; callback.Invoke(response); return response; } //return response, if callback is set (method is asynchronous) - result could be empty string and future result operations //will be processed in the callback return new JsonResponse() { Result = results }; } catch (Exception ex) { JsonResponse response; if (ex is TargetParameterCountException) { response = new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32602, "Invalid params", ex)) }; callback.Invoke(response); return response; } // We really dont care about the TargetInvocationException, just pass on the inner exception if (ex is JsonRpcException) { response = new JsonResponse() { Error = ProcessException(Rpc, ex as JsonRpcException) }; callback.Invoke(response); return response; } if (ex.InnerException != null && ex.InnerException is JsonRpcException) { response = new JsonResponse() { Error = ProcessException(Rpc, ex.InnerException as JsonRpcException) }; callback.Invoke(response); return response; } else if (ex.InnerException != null) { response = new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32603, "Internal Error", ex.InnerException)) }; callback.Invoke(response); return response; } response = new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32603, "Internal Error", ex)) }; callback.Invoke(response); return response; } finally { RemoveRpcContext(); } }
/// <summary> /// Invokes a method to handle a JsonRpc request. /// </summary> /// <param name="Rpc">JsonRpc Request to be processed</param> /// <param name="RpcContext">Optional context that will be available from within the jsonRpcMethod.</param> /// <returns></returns> public JsonResponse Handle(JsonRequest Rpc, Object RpcContext = null) { AddRpcContext(RpcContext); var preProcessingException = PreProcess(Rpc, RpcContext); if (preProcessingException != null) { return new JsonResponse() { Error = preProcessingException, Id = Rpc.Id }; } SMDService metadata = null; Delegate handle = null; var haveDelegate = this.Handlers.TryGetValue(Rpc.Method, out handle); var haveMetadata = this.MetaData.Services.TryGetValue(Rpc.Method, out metadata); if (haveDelegate == false || haveMetadata == false || metadata == null || handle == null) { return new JsonResponse() { Result = null, Error = new JsonRpcException(-32601, "Method not found", "The method does not exist / is not available."), Id = Rpc.Id }; } if (Rpc.Params is ICollection == false) { return new JsonResponse() { Result = null, Error = new JsonRpcException(-32602, "Invalid params", "The number of parameters could not be counted"), Id = Rpc.Id }; } bool isJObject = Rpc.Params is Newtonsoft.Json.Linq.JObject; bool isJArray = Rpc.Params is Newtonsoft.Json.Linq.JArray; object[] parameters = null; bool expectsRefException = false; var metaDataParamCount = metadata.parameters.Count(x => x != null); var getCount = Rpc.Params as ICollection; var loopCt = getCount.Count; var paramCount = loopCt; if (paramCount == metaDataParamCount - 1 && metadata.parameters[metaDataParamCount-1].ObjectType.Name.Contains(typeof(JsonRpcException).Name)) { paramCount++; expectsRefException = true; } parameters = new object[paramCount]; if (isJArray) { var jarr = ((Newtonsoft.Json.Linq.JArray)Rpc.Params); //var loopCt = jarr.Count; //var pCount = loopCt; //if (pCount == metaDataParamCount - 1 && metadata.parameters[metaDataParamCount].GetType() == typeof(JsonRpcException)) // pCount++; //parameters = new object[pCount]; for (int i = 0; i < loopCt; i++) { parameters[i] = CleanUpParameter(jarr[i], metadata.parameters[i]); } } else if (isJObject) { var jo = Rpc.Params as Newtonsoft.Json.Linq.JObject; //var loopCt = jo.Count; //var pCount = loopCt; //if (pCount == metaDataParamCount - 1 && metadata.parameters[metaDataParamCount].GetType() == typeof(JsonRpcException)) // pCount++; //parameters = new object[pCount]; var asDict = jo as IDictionary<string, Newtonsoft.Json.Linq.JToken>; for (int i = 0; i < loopCt; i++) { if (asDict.ContainsKey(metadata.parameters[i].Name) == false) { return new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32602, "Invalid params", string.Format("Named parameter '{0}' was not present.", metadata.parameters[i].Name) )) ,Id = Rpc.Id }; } parameters[i] = CleanUpParameter(jo[metadata.parameters[i].Name], metadata.parameters[i]); } } // Optional Parameter support // check if we still miss parameters compared to metadata which may include optional parameters. // if the rpc-call didn't supply a value for an optional parameter, we should be assinging the default value of it. if (parameters.Length < metaDataParamCount && metadata.defaultValues.Length > 0) // rpc call didn't set values for all optional parameters, so we need to assign the default values for them. { var paramIndex = parameters.Length; // the index we should start storing default values of optional parameters. var missingParamsCount = metaDataParamCount - parameters.Length; // the amount of optional parameters without a value set by rpc-call. Array.Resize(ref parameters, parameters.Length + missingParamsCount); // resize the array to include all optional parameters. // we need to add in reverse order as parameters can appear after all required parameters. // as some of the optional parameters could already have assigned their values in rpc-call, // by starting from the end we can make sure we only add the required default values. for (int k = missingParamsCount; k > 0; k--) { var optionalParamIndex = k - 1; // the index of the optional parameter we will be currently setting a default value. parameters[paramIndex] = metadata.defaultValues[optionalParamIndex].Value; // set the default value for the optional parameter that rpc-call didn't set a value for. paramIndex++; paramCount++; // we need to increase the paramCount by one each time we add default-value for an optional parameter that rpc-call didn't set a value for. } } if (parameters.Length != metaDataParamCount) { return new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32602, "Invalid params", string.Format("Expecting {0} parameters, and received {1}", metadata.parameters.Length, parameters.Length) )), Id = Rpc.Id }; } try { var results = handle.DynamicInvoke(parameters); var last = parameters.Length>0 ? parameters[paramCount - 1]:null; JsonRpcException contextException; if (Task.CurrentId.HasValue && RpcExceptions.TryRemove(Task.CurrentId.Value, out contextException)) { return new JsonResponse() { Error = ProcessException(Rpc, contextException), Id = Rpc.Id }; } if (expectsRefException && last != null && last is JsonRpcException) { return new JsonResponse() { Error = ProcessException(Rpc, last as JsonRpcException), Id = Rpc.Id }; } return new JsonResponse() { Result = results }; } catch (Exception ex) { if (ex is TargetParameterCountException) { return new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32602, "Invalid params", ex)) }; } // We really dont care about the TargetInvocationException, just pass on the inner exception if (ex is JsonRpcException) { return new JsonResponse() { Error = ProcessException(Rpc, ex as JsonRpcException) }; } if (ex.InnerException != null && ex.InnerException is JsonRpcException) { return new JsonResponse() { Error = ProcessException(Rpc, ex.InnerException as JsonRpcException) }; } else if (ex.InnerException != null) { return new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32603, "Internal Error", ex.InnerException)) }; } return new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32603, "Internal Error", ex)) }; } finally { RemoveRpcContext(); } }
public JsonRpcException PostProcess(JsonRequest rpc, JsonResponse response, object context) { run++; this.rpc = rpc; this.response = response; this.context = context; if (changeResponse_) { return new JsonRpcException(-123, "Test error", null); } return null; }
private JsonRpcException PreProcess(JsonRequest request, object context) { if (externalPreProcessingHandler == null) return null; return externalPreProcessingHandler(request, context); }
public IObservable <JsonResponse <T> > Invoke <T>(JsonRequest jsonRpc, IScheduler scheduler) { var res = Observable.Create <JsonResponse <T> >((obs) => scheduler.Schedule(() => { WebRequest req = null; try { int myId; lock (idLock) { myId = ++id; } jsonRpc.Id = myId.ToString(); req = HttpWebRequest.Create(new Uri(ServiceEndpoint, "?callid=" + myId.ToString())); req.Method = "Post"; req.ContentType = "application/json-rpc"; } catch (Exception ex) { obs.OnError(ex); } var ar = req.BeginGetRequestStream(new AsyncCallback((iar) => { HttpWebRequest request = null; try { request = (HttpWebRequest)iar.AsyncState; var stream = new StreamWriter(req.EndGetRequestStream(iar)); var json = Newtonsoft.Json.JsonConvert.SerializeObject(jsonRpc); stream.Write(json); stream.Close(); } catch (Exception ex) { obs.OnError(ex); } var rar = req.BeginGetResponse(new AsyncCallback((riar) => { JsonResponse <T> rjson = null; string sstream = ""; try { var request1 = (HttpWebRequest)riar.AsyncState; var resp = (HttpWebResponse)request1.EndGetResponse(riar); using (var rstream = new StreamReader(CopyAndClose(resp.GetResponseStream()))) { sstream = rstream.ReadToEnd(); } rjson = Newtonsoft.Json.JsonConvert.DeserializeObject <JsonResponse <T> >(sstream); } catch (Exception ex) { Debug.WriteLine(ex.Message); Debugger.Break(); } if (rjson == null) { if (!string.IsNullOrEmpty(sstream)) { JObject jo = Newtonsoft.Json.JsonConvert.DeserializeObject(sstream) as JObject; obs.OnError(new Exception(jo["Error"].ToString())); } else { obs.OnError(new Exception("Empty response")); } } obs.OnNext(rjson); obs.OnCompleted(); }), request); }), req); })); return(res); }