def call(self, method, *args, **kwargs): """ Creates the JSON-RPC request string, calls the HTTP server, converts JSON-RPC response string to python and returns the result. :param method: Name of the method which will be called on the HTTP server. Or a list with RPC-Request-Dictionaries. Syntax:: "<MethodName>" or [<JsonRpcRequestDict>, ...] RPC-Request-Dictionaries will be made with the function *rpcrequest.create_request_dict()*. """ # Create JSON-RPC-request if isinstance(method, string_types): request_json = rpcrequest.create_request_json(method, *args, **kwargs) else: assert not args and not kwargs request_json = rpcjson.dumps(method) # Call the HTTP-JSON-RPC server response_json = http_request( url = self.url, json_string = request_json, username = self.username, password = self.password, timeout = self.timeout, additional_headers = self.additional_headers, content_type = self.content_type, cookies = self.cookies, gzipped = self.gzipped, ssl_context = self.ssl_context, debug = self.debug ) if not response_json: return # Convert JSON-RPC-response to python-object response = rpcresponse.parse_response_json(response_json) if isinstance(response, rpcresponse.Response): if response.error: # Raise error if response.error.code in rpcerror.jsonrpcerrors: raise rpcerror.jsonrpcerrors[response.error.code]( message = response.error.message, data = response.error.data ) else: raise rpcerror.JsonRpcError( message = response.error.message, data = response.error.data, code = response.error.code ) else: # Return result return response.result elif isinstance(response, list): # Bei Listen wird keine Fehlerauswerung gemacht return response
def call(self, method, *args, **kwargs): """ Creates the JSON-RPC request string, calls the HTTP server, converts JSON-RPC response string to python and returns the result. :param method: Name of the method which will be called on the HTTP server. Or a list with RPC-Request-Dictionaries. Syntax:: "<MethodName>" or [<JsonRpcRequestDict>, ...] RPC-Request-Dictionaries will be made with the function *rpcrequest.create_request_dict()*. """ # Create JSON-RPC-request if isinstance(method, basestring): request_json = rpcrequest.create_request_json(method, *args, **kwargs) else: assert not args and not kwargs request_json = rpcjson.dumps(method) # Call the HTTP-JSON-RPC server response_json = http_request( url = self.url, json_string = request_json, username = self.username, password = self.password, timeout = self.timeout, additional_headers = self.additional_headers, content_type = self.content_type, cookies = self.cookies, gzipped = self.gzipped, ssl_context = self.ssl_context, debug = self.debug ) if not response_json: return # Convert JSON-RPC-response to python-object response = rpcresponse.parse_response_json(response_json) if isinstance(response, rpcresponse.Response): if response.error: # Raise error if response.error.code in rpcerror.jsonrpcerrors: raise rpcerror.jsonrpcerrors[response.error.code]( message = response.error.message, data = response.error.data ) else: raise rpcerror.JsonRpcError( message = response.error.message, data = response.error.data, code = response.error.code ) else: # Return result return response.result elif isinstance(response, list): # Bei Listen wird keine Fehlerauswerung gemacht return response
def request_handler(self, *args, **kwargs): """ Json-RPC Handler """ if cherrypy.request.method == "GET": # GET # Arguments jsonrpc = kwargs.get("jsonrpc") id = kwargs.get("id") method = kwargs.get("method") if not method: # Bad Request raise cherrypy.HTTPError(httplib.BAD_REQUEST) # params _args = [] _kwargs = {} params = kwargs.get("params") if params: params = rpcjson.loads(params) if isinstance(params, list): _args = params _kwargs = {} elif isinstance(params, dict): _args = [] _kwargs = params # Create JSON request string request_dict = rpcrequest.create_request_dict( method, *_args, **_kwargs) request_dict["jsonrpc"] = jsonrpc request_dict["id"] = id request_json = rpcjson.dumps(request_dict) else: # POST if "gzip" in cherrypy.request.headers.get("Content-Encoding", ""): request_json = decompress(cherrypy.request.body.read()) else: request_json = cherrypy.request.body.read() # Call method result_string = self.call(request_json) or "" # Return JSON-String cherrypy.response.headers["Cache-Control"] = "no-cache" cherrypy.response.headers["Pragma"] = "no-cache" cherrypy.response.headers["Content-Type"] = "application/json" if "gzip" in cherrypy.request.headers.get("Accept-Encoding", ""): # Gzip-compressed cherrypy.response.headers["Content-Encoding"] = "gzip" return compress(result_string, compress_level=5) else: # uncompressed return result_string
def create_request_json(method, *args, **kwargs): """ Returns a JSON-RPC-String for a method :param method: Name of the method :param args: Positional parameters :param kwargs: Named parameters """ return rpcjson.dumps(create_request_dict(method, *args, **kwargs))
def request_handler(self, *args, **kwargs): """ Json-RPC Handler """ if cherrypy.request.method == "GET": # GET # Arguments jsonrpc = kwargs.get("jsonrpc") id = kwargs.get("id") method = kwargs.get("method") if not method: # Bad Request raise cherrypy.HTTPError(httplib.BAD_REQUEST) # params _args = [] _kwargs = {} params = kwargs.get("params") if params: params = rpcjson.loads(params) if isinstance(params, list): _args = params _kwargs = {} elif isinstance(params, dict): _args = [] _kwargs = params # Create JSON request string request_dict = rpcrequest.create_request_dict(method, *_args, **_kwargs) request_dict["jsonrpc"] = jsonrpc request_dict["id"] = id request_json = rpcjson.dumps(request_dict) else: # POST if "gzip" in cherrypy.request.headers.get("Content-Encoding", ""): request_json = decompress(cherrypy.request.body.read()) else: request_json = cherrypy.request.body.read() # Call method result_string = self.call(request_json) or "" # Return JSON-String cherrypy.response.headers["Cache-Control"] = "no-cache" cherrypy.response.headers["Pragma"] = "no-cache" cherrypy.response.headers["Content-Type"] = "application/json" if "gzip" in cherrypy.request.headers.get("Accept-Encoding", ""): # Gzip-compressed cherrypy.response.headers["Content-Encoding"] = "gzip" return compress(result_string, compress_level = 5) else: # uncompressed return result_string
def handle_cgi_request(methods = None): """ Gets the JSON-RPC request from CGI environment and returns the result to STDOUT """ import cgi import cgitb cgitb.enable() # get response-body request_json = sys.stdin.read() if request_json: # POST request_json = urlparse.unquote(request_json) else: # GET args = [] kwargs = {} fields = cgi.FieldStorage() jsonrpc = fields.getfirst("jsonrpc") id = fields.getfirst("id") method = fields.getfirst("method") params = fields.getfirst("params") if params: params = rpcjson.loads(params) if isinstance(params, list): args = params kwargs = {} elif isinstance(params, dict): args = [] kwargs = params # Create JSON request string request_dict = rpcrequest.create_request_dict(method, *args, **kwargs) request_dict["jsonrpc"] = jsonrpc request_dict["id"] = id request_json = rpcjson.dumps(request_dict) # Call response_json = rpclib.JsonRpc(methods = methods).call(request_json) # Return headers print("Content-Type: application/json") print("Cache-Control: no-cache") print("Pragma: no-cache") print() # Return result print(response_json)
def handle_cgi_request(methods = None): """ Gets the JSON-RPC request from CGI environment and returns the result to STDOUT """ import cgi import cgitb cgitb.enable() # get response-body request_json = sys.stdin.read() if request_json: # POST request_json = urlparse.unquote(request_json) else: # GET args = [] kwargs = {} fields = cgi.FieldStorage() jsonrpc = fields.getfirst("jsonrpc") id = fields.getfirst("id") method = fields.getfirst("method") params = fields.getfirst("params") if params: params = rpcjson.loads(params) if isinstance(params, list): args = params kwargs = {} elif isinstance(params, dict): args = [] kwargs = params # Create JSON request string request_dict = rpcrequest.create_request_dict(method, *args, **kwargs) request_dict["jsonrpc"] = jsonrpc request_dict["id"] = id request_json = rpcjson.dumps(request_dict) # Call response_json = rpclib.JsonRpc(methods = methods).call(request_json) # Return headers print "Content-Type: application/json" print "Cache-Control: no-cache" print "Pragma: no-cache" print # Return result print response_json
def to_string(self): """ Returns a Json-string """ positional_params, named_params = self.get_splitted_params() # Create dictionary if named_params: params = named_params if positional_params: params["__args"] = positional_params else: params = positional_params data = { "method": self.method, "id": self.id, "jsonrpc": self.jsonrpc or "2.0", "params": params } # Return Json return rpcjson.dumps(data)
) # Convert responses to dictionaries and filter it responses_ = [] for response in responses: if ( bool(response.id) or bool(unicode(response.id)) if response.id is not None else False ): responses_.append(response.to_dict()) responses = responses_ # Return as JSON-string (batch or normal) if responses: if len(requests) == 1: return rpcjson.dumps(responses[0]) elif len(requests) > 1: return rpcjson.dumps(responses) def __call__(self, json_request): """ Redirects the requests to *self.call* """ return self.call(json_request) def __getitem__(self, key): """ Gets back the requested method
def do_GET(self): """ Handles HTTP-GET-Request """ # Parse URL query path, query_str = urllib.splitquery(self.path) if not query_str: # Bad Request return self.send_error(httplib.BAD_REQUEST) # Parse querystring query = urlparse.parse_qs(query_str) # jsonrpc jsonrpc = query.get("jsonrpc") if jsonrpc: jsonrpc = jsonrpc[0] # id id = query.get("id") if id: id = id[0] # method method = query.get("method") if method: method = method[0] else: # Bad Request return self.send_error(httplib.BAD_REQUEST) # params args = [] kwargs = {} params = query.get("params") if params: params = rpcjson.loads(params[0]) if isinstance(params, list): args = params kwargs = {} elif isinstance(params, dict): args = [] kwargs = params # Create JSON request string request_dict = rpcrequest.create_request_dict(method, *args, **kwargs) request_dict["jsonrpc"] = jsonrpc request_dict["id"] = id request_json = rpcjson.dumps(request_dict) # Call response_json = self.call(request_json) or "" # Return result self.send_response(code = httplib.OK) self.set_content_type(self.content_type) self.set_no_cache() self.set_content_length(len(response_json)) self.end_headers() self.wfile.write(response_json)
def to_string(self): """ Returns the response as JSON-string """ return rpcjson.dumps(self.to_dict())
def do_GET(self): """ Handles HTTP-GET-Request """ # Parse URL query path, query_str = urllib.splitquery(self.path) if not query_str: # Bad Request return self.send_error(httplib.BAD_REQUEST) # Parse querystring query = urlparse.parse_qs(query_str) # jsonrpc jsonrpc = query.get("jsonrpc") if jsonrpc: jsonrpc = jsonrpc[0] # id id = query.get("id") if id: id = id[0] # method method = query.get("method") if method: method = method[0] else: # Bad Request return self.send_error(httplib.BAD_REQUEST) # params args = [] kwargs = {} params = query.get("params") if params: params = rpcjson.loads(params[0]) if isinstance(params, list): args = params kwargs = {} elif isinstance(params, dict): args = [] kwargs = params # Create JSON request string request_dict = rpcrequest.create_request_dict(method, *args, **kwargs) request_dict["jsonrpc"] = jsonrpc request_dict["id"] = id request_json = rpcjson.dumps(request_dict) # Call response_json = self.call(request_json) or "" # Return result self.send_response(code=httplib.OK) self.set_content_type(self.content_type) self.set_no_cache() self.set_content_length(len(response_json)) self.end_headers() self.wfile.write(response_json)
def call(self, json_request): """ Parses the *json_request*, calls the function(s) and returns the *json_response*. :param json_request: JSON-RPC-string with one or more JSON-RPC-requests :return: JSON-RPC-string with one or more responses. """ # List for the responses responses = [] # List with requests requests = rpcrequest.parse_request_json(json_request) if not isinstance(requests, list): requests = [requests] # Every JSON-RPC request in a batch of requests for request in requests: # Request-Data jsonrpc = request.jsonrpc id = request.id method = request.get("method", "") if method not in self.methods: # Check if requested method is signed as *rpcmethod* _method = getattr(self, method, None) if (_method and callable(_method) and getattr(_method, "rpcmethod", False)): self.methods[method] = _method if method not in self.methods: # Method not found error error = rpcerror.MethodNotFound(data="Method name: '%s'" % method) responses.append( rpcresponse.Response(jsonrpc=jsonrpc, id=id, error=error)) # Logging error logging_error_str = "{error} -- {data}" logging.error( logging_error_str.format(error=safe_unicode(error), data=safe_unicode(error.data))) continue # split positional and named params positional_params, named_params = request.get_splitted_params() # Call the method with parameters try: rpc_function = self.methods[method] result = rpc_function(*positional_params, **named_params) responses.append( rpcresponse.Response(jsonrpc=jsonrpc, id=id, result=result)) except TypeError as err: traceback_info = rpcerror.get_traceback_string() if "takes exactly" in safe_unicode( err) and "arguments" in safe_unicode(err): error = rpcerror.InvalidParams(data=traceback_info) responses.append( rpcresponse.Response(jsonrpc=jsonrpc, id=id, error=error)) # Logging error logging_error_str = "{error} -- {data}" logging.error( logging_error_str.format(error=safe_unicode(error), data=safe_unicode( error.data))) else: error = rpcerror.InternalError(data=traceback_info) responses.append( rpcresponse.Response(jsonrpc=jsonrpc, id=id, error=error)) # Logging error logging_error_str = "{error} -- {data}" logging.error( logging_error_str.format(error=safe_unicode(error), data=safe_unicode( error.data))) except rpcerror.JsonRpcError as err: responses.append( rpcresponse.Response(jsonrpc=jsonrpc, id=id, error=err)) # Logging error logging_error_str = "{error} -- {data}" logging.error( logging_error_str.format(error=safe_unicode(err), data=safe_unicode(err.data))) except Exception as err: traceback_info = rpcerror.get_traceback_string() if hasattr(err, "data"): error_data = err.data else: error_data = None error = rpcerror.InternalError( message=safe_unicode(err), data=safe_unicode(error_data or traceback_info)) responses.append( rpcresponse.Response(jsonrpc=jsonrpc, id=id, error=error)) # Logging error logging_error_str = "{error} -- {data}" logging.error( logging_error_str.format(error=safe_unicode(error), data=safe_unicode(error.data))) # Convert responses to dictionaries and filter it responses_ = [] for response in responses: if (bool(response.id) or bool(unicode(response.id)) if response.id is not None else False): responses_.append(response.to_dict()) responses = responses_ # Return as JSON-string (batch or normal) if responses: if len(requests) == 1: return rpcjson.dumps(responses[0]) elif len(requests) > 1: return rpcjson.dumps(responses)
jsonrpc=jsonrpc, id=id, error=rpcerror.InternalError( data=error_data or traceback_info))) # Convert responses to dictionaries and filter it responses_ = [] for response in responses: if response.id: responses_.append(response.to_dict()) responses = responses_ # Return as JSON-string (batch or normal) if responses: if len(requests) == 1: return rpcjson.dumps(responses[0]) elif len(requests) > 1: return rpcjson.dumps(responses) def __call__(self, json_request): """ Redirects the requests to *self.call* """ return self.call(json_request) def __getitem__(self, key): """ Gets back the requested method """
def call(self, json_request): """ Parses the *json_request*, calls the function(s) and returns the *json_response*. :param json_request: JSON-RPC-string with one or more JSON-RPC-requests :return: JSON-RPC-string with one or more responses. """ # List for the responses responses = [] # List with requests requests = rpcrequest.parse_request_json(json_request) if not isinstance(requests, list): requests = [requests] # Every JSON-RPC request in a batch of requests for request in requests: # Request-Data jsonrpc = request.jsonrpc id = request.id method = request.get("method", "") if method not in self.methods: # Check if requested method is signed as *rpcmethod* _method = getattr(self, method, None) if _method and callable(_method) and getattr(_method, "rpcmethod", False): self.methods[method] = _method if method not in self.methods: # Method not found error error = rpcerror.MethodNotFound(data=u"Method name: '%s'" % method) responses.append(rpcresponse.Response(jsonrpc=jsonrpc, id=id, error=error)) # Logging error logging.error(u"{error} -- {data}".format(error=safe_unicode(error), data=safe_unicode(error.data))) continue # split positional and named params positional_params, named_params = request.get_splitted_params() # Call the method with parameters try: rpc_function = self.methods[method] result = rpc_function(*positional_params, **named_params) responses.append(rpcresponse.Response(jsonrpc=jsonrpc, id=id, result=result)) except TypeError as err: traceback_info = rpcerror.get_traceback_string() if "takes exactly" in safe_unicode(err) and "arguments" in safe_unicode(err): error = rpcerror.InvalidParams(data=traceback_info) responses.append(rpcresponse.Response(jsonrpc=jsonrpc, id=id, error=error)) # Logging error logging.error(u"{error} -- {data}".format(error=safe_unicode(error), data=safe_unicode(error.data))) else: error = rpcerror.InternalError(data=traceback_info) responses.append(rpcresponse.Response(jsonrpc=jsonrpc, id=id, error=error)) # Logging error logging.error(u"{error} -- {data}".format(error=safe_unicode(error), data=safe_unicode(error.data))) except rpcerror.JsonRpcError as err: responses.append(rpcresponse.Response(jsonrpc=jsonrpc, id=id, error=err)) # Logging error logging.error(u"{error} -- {data}".format(error=safe_unicode(err), data=safe_unicode(err.data))) except StandardError as err: traceback_info = rpcerror.get_traceback_string() if hasattr(err, "data"): error_data = err.data else: error_data = None error = rpcerror.InternalError( message=safe_unicode(err), data=safe_unicode(error_data or traceback_info) ) responses.append(rpcresponse.Response(jsonrpc=jsonrpc, id=id, error=error)) # Logging error logging.error(u"{error} -- {data}".format(error=safe_unicode(error), data=safe_unicode(error.data))) # Convert responses to dictionaries and filter it responses_ = [] for response in responses: if bool(response.id) or bool(unicode(response.id)) if response.id is not None else False: responses_.append(response.to_dict()) responses = responses_ # Return as JSON-string (batch or normal) if responses: if len(requests) == 1: return rpcjson.dumps(responses[0]) elif len(requests) > 1: return rpcjson.dumps(responses)