Decoupled SimpleXMLRPCRequestHandler subclass
and added simple introspection
This commit is contained in:
parent
f4bf3bac2a
commit
6a089e0f88
60
src/api.py
60
src/api.py
|
@ -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__
|
||||||
|
|
Reference in New Issue
Block a user