Decoupled SimpleXMLRPCRequestHandler subclass

and added simple introspection
This commit is contained in:
Dmitri Bogomolov 2018-10-25 17:52:19 +03:00
parent f4bf3bac2a
commit 6a089e0f88
Signed by untrusted user: g1itch
GPG Key ID: 720A756F18DEED13
1 changed files with 37 additions and 23 deletions

View File

@ -68,9 +68,8 @@ class StoppableXMLRPCServer(SimpleXMLRPCServer):
"""A SimpleXMLRPCServer that honours state.shutdown""" """A SimpleXMLRPCServer that honours state.shutdown"""
allow_reuse_address = True allow_reuse_address = True
def serve_forever(self): def serve_forever(self, poll_interval=None):
"""Start the SimpleXMLRPCServer""" """Start the SimpleXMLRPCServer"""
# pylint: disable=arguments-differ
while state.shutdown == 0: while state.shutdown == 0:
self.handle_request() self.handle_request()
@ -121,6 +120,7 @@ class singleAPI(StoppableThread):
'bitmessagesettings', 'apiport', str(port)) 'bitmessagesettings', 'apiport', str(port))
BMConfigParser().save() BMConfigParser().save()
break break
se.register_instance(BMXMLRPCDispatcher())
se.register_introspection_functions() se.register_introspection_functions()
apiNotifyPath = BMConfigParser().safeGet( apiNotifyPath = BMConfigParser().safeGet(
@ -185,9 +185,8 @@ class command(object):
# Modified by Jonathan Warren (Atheros). # Modified by Jonathan Warren (Atheros).
# Further modified by the Bitmessage developers # Further modified by the Bitmessage developers
# http://code.activestate.com/recipes/501148 # http://code.activestate.com/recipes/501148
class BMXMLRPCRequestHandler(SimpleXMLRPCRequestHandler, object): class BMXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
"""The main API handler""" """The main API handler"""
__metaclass__ = CommandHandler
def do_POST(self): def do_POST(self):
""" """
@ -219,16 +218,28 @@ class BMXMLRPCRequestHandler(SimpleXMLRPCRequestHandler, object):
size_remaining -= len(L[-1]) size_remaining -= len(L[-1])
data = ''.join(L) data = ''.join(L)
# In previous versions of SimpleXMLRPCServer, _dispatch # pylint: disable=attribute-defined-outside-init
# could be overridden in this class, instead of in self.cookies = []
# SimpleXMLRPCDispatcher. To maintain backwards compatibility,
# check to see if a subclass implements _dispatch and dispatch validuser = self.APIAuthenticateClient()
# using that method if present. if not validuser:
# pylint: disable=protected-access time.sleep(2)
response = self.server._marshaled_dispatch( # ProtocolError?
data, getattr(self, '_dispatch', None) response = (
) "RPC Username or password incorrect or HTTP header"
except BaseException: # This should only happen if the module is buggy " lacks authentication at all."
)
else:
# In previous versions of SimpleXMLRPCServer, _dispatch
# could be overridden in this class, instead of in
# SimpleXMLRPCDispatcher. To maintain backwards compatibility,
# check to see if a subclass implements _dispatch and dispatch
# using that method if present.
# pylint: disable=protected-access
response = self.server._marshaled_dispatch(
data, getattr(self, '_dispatch', None)
)
except Exception: # This should only happen if the module is buggy
# internal error, report as HTTP server error # internal error, report as HTTP server error
self.send_response(500) self.send_response(500)
self.end_headers() self.end_headers()
@ -276,6 +287,11 @@ class BMXMLRPCRequestHandler(SimpleXMLRPCRequestHandler, object):
return False return False
class BMXMLRPCDispatcher(object):
"""This class is used to dispatch API commands"""
__metaclass__ = CommandHandler
def _decode(self, text, decode_type): def _decode(self, text, decode_type):
try: try:
if decode_type == 'hex': if decode_type == 'hex':
@ -1216,15 +1232,6 @@ class BMXMLRPCRequestHandler(SimpleXMLRPCRequestHandler, object):
state.last_api_response = time.time() state.last_api_response = time.time()
def _dispatch(self, method, params): def _dispatch(self, method, params):
# pylint: disable=attribute-defined-outside-init
self.cookies = []
validuser = self.APIAuthenticateClient()
if not validuser:
time.sleep(2)
# ProtocolError?
return "RPC Username or password incorrect or HTTP header lacks authentication at all."
_fault = None _fault = None
try: try:
@ -1246,3 +1253,10 @@ class BMXMLRPCRequestHandler(SimpleXMLRPCRequestHandler, object):
return str(_fault) return str(_fault)
else: else:
raise _fault # pylint: disable=raising-bad-type raise _fault # pylint: disable=raising-bad-type
def _listMethods(self):
"""List all API commands"""
return self._handlers.keys()
def _methodHelp(self, method):
return self._handlers[method].__doc__