Implemented JSON-RPC apivariant

This commit is contained in:
Dmitri Bogomolov 2018-10-26 00:19:07 +03:00
parent 6a089e0f88
commit 726986c1eb
Signed by untrusted user: g1itch
GPG Key ID: 720A756F18DEED13
2 changed files with 28 additions and 14 deletions

View File

@ -11,6 +11,7 @@ from src.version import softwareVersion
EXTRAS_REQUIRE = { EXTRAS_REQUIRE = {
'gir': ['pygobject'], 'gir': ['pygobject'],
'json': ['jsonrpclib'],
'notify2': ['notify2'], 'notify2': ['notify2'],
'opencl': ['pyopencl', 'numpy'], 'opencl': ['pyopencl', 'numpy'],
'prctl': ['python_prctl'], # Named threads 'prctl': ['python_prctl'], # Named threads

View File

@ -54,6 +54,7 @@ except ImportError:
else: else:
monkey_patch() monkey_patch()
str_chan = '[chan]' str_chan = '[chan]'
str_broadcast_subscribers = '[Broadcast subscribers]' str_broadcast_subscribers = '[Broadcast subscribers]'
@ -64,16 +65,6 @@ class APIError(xmlrpclib.Fault):
return "API Error %04i: %s" % (self.faultCode, self.faultString) return "API Error %04i: %s" % (self.faultCode, self.faultString)
class StoppableXMLRPCServer(SimpleXMLRPCServer):
"""A SimpleXMLRPCServer that honours state.shutdown"""
allow_reuse_address = True
def serve_forever(self, poll_interval=None):
"""Start the SimpleXMLRPCServer"""
while state.shutdown == 0:
self.handle_request()
# This thread, of which there is only one, runs the API. # This thread, of which there is only one, runs the API.
class singleAPI(StoppableThread): class singleAPI(StoppableThread):
"""API thread""" """API thread"""
@ -99,17 +90,38 @@ class singleAPI(StoppableThread):
getattr(errno, 'WSAEADDRINUSE') getattr(errno, 'WSAEADDRINUSE')
except AttributeError: except AttributeError:
errno.WSAEADDRINUSE = errno.EADDRINUSE errno.WSAEADDRINUSE = errno.EADDRINUSE
RPCServerBase = SimpleXMLRPCServer
if BMConfigParser().safeGet(
'bitmessagesettings', 'apivariant') == 'json':
try:
from jsonrpclib.SimpleJSONRPCServer import (
SimpleJSONRPCServer as RPCServerBase)
except ImportError:
logger.warning(
'jsonrpclib not available, failing back to XML-RPC')
# Nested class. FIXME not found a better solution.
class StoppableRPCServer(RPCServerBase):
"""A SimpleXMLRPCServer that honours state.shutdown"""
allow_reuse_address = True
def serve_forever(self, poll_interval=None):
"""Start the RPCServer"""
while state.shutdown == 0:
self.handle_request()
for attempt in range(50): for attempt in range(50):
try: try:
if attempt > 0: if attempt > 0:
logger.warning( logger.warning(
'Failed to start API listener on port %s', port) 'Failed to start API listener on port %s', port)
port = random.randint(32767, 65535) port = random.randint(32767, 65535)
se = StoppableXMLRPCServer( se = StoppableRPCServer(
(BMConfigParser().get( (BMConfigParser().get(
'bitmessagesettings', 'apiinterface'), 'bitmessagesettings', 'apiinterface'),
port), port),
BMXMLRPCRequestHandler, True, True) BMXMLRPCRequestHandler, True, encoding='UTF-8')
except socket.error as e: except socket.error as e:
if e.errno in (errno.EADDRINUSE, errno.WSAEADDRINUSE): if e.errno in (errno.EADDRINUSE, errno.WSAEADDRINUSE):
continue continue
@ -120,7 +132,8 @@ class singleAPI(StoppableThread):
'bitmessagesettings', 'apiport', str(port)) 'bitmessagesettings', 'apiport', str(port))
BMConfigParser().save() BMConfigParser().save()
break break
se.register_instance(BMXMLRPCDispatcher())
se.register_instance(BMRPCDispatcher())
se.register_introspection_functions() se.register_introspection_functions()
apiNotifyPath = BMConfigParser().safeGet( apiNotifyPath = BMConfigParser().safeGet(
@ -288,7 +301,7 @@ class BMXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
return False return False
class BMXMLRPCDispatcher(object): class BMRPCDispatcher(object):
"""This class is used to dispatch API commands""" """This class is used to dispatch API commands"""
__metaclass__ = CommandHandler __metaclass__ = CommandHandler