J
Jason Kratz
After figuring out the other day (thanks to everyone here who helped)
how to get the dir lists I want on my unix machine I want to turn the
same thing into an XML-RPC service. Using Simple XMLRPCServer.py I
created my own version by adding my getdirs function and then I call the
code to open the server:
import os
import os.path
import SimpleXMLRPCServer
import xmlrpclib
import SocketServer
import BaseHTTPServer
import sys
class SimpleXMLRPCRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_POST(self):
"""Handles the HTTP POST request.
Attempts to interpret all HTTP POST requests as XML-RPC calls,
which are forwarded to the _dispatch method for handling.
"""
try:
# get arguments
data = self.rfile.read(int(self.headers["content-length"]))
params, method = xmlrpclib.loads(data)
# generate response
try:
response = self._dispatch(method, params)
# wrap response in a singleton tuple
response = (response,)
except:
# report exception back to server
response = xmlrpclib.dumps(
xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type,
sys.exc_value))
)
else:
response = xmlrpclib.dumps(response, methodresponse=1)
except:
# internal error, report as HTTP server error
self.send_response(500)
self.end_headers()
else:
# got a valid XML RPC response
self.send_response(200)
self.send_header("Content-type", "text/xml")
self.send_header("Content-length", str(len(response)))
self.end_headers()
self.wfile.write(response)
# shut down the connection
self.wfile.flush()
self.connection.shutdown(1)
def _dispatch(self, method, params):
func = None
try:
# check to see if a matching function has been registered
func = self.server.funcs[method]
except KeyError:
if self.server.instance is not None:
# check for a _dispatch method
if hasattr(self.server.instance, '_dispatch'):
return self.server.instance._dispatch(method, params)
else:
# call instance method directly
try:
func = _resolve_dotted_attribute(
self.server.instance,
method
)
except AttributeError:
pass
if func is not None:
return apply(func, params)
else:
raise Exception('method "%s" is not supported' % method)
def log_request(self, code='-', size='-'):
"""Selectively log an accepted request."""
if self.server.logRequests:
BaseHTTPServer.BaseHTTPRequestHandler.log_request(self,
code, size)
def _resolve_dotted_attribute(obj, attr):
"""Resolves a dotted attribute name to an object. Raises
an AttributeError if any attribute in the chain starts with a '_'.
"""
for i in attr.split('.'):
if i.startswith('_'):
raise AttributeError(
'attempt to access private attribute "%s"' % i
)
else:
obj = getattr(obj,i)
return obj
class SimpleXMLRPCServer(SocketServer.TCPServer):
def __init__(self, addr, requestHandler=SimpleXMLRPCRequestHandler,
logRequests=1):
self.funcs = {}
self.logRequests = logRequests
self.instance = None
SocketServer.TCPServer.__init__(self, addr, requestHandler)
def register_instance(self, instance):
self.instance = instance
def register_function(self, function, name = None):
if name is None:
name = function.__name__
self.funcs[name] = function
def getdirs(path):
dirs=[]
for entry in os.listdir(path):
entry=os.path.join(path,entry)
if os.path.isdir(entry):
dirs.append(entry)
return dirs
server = SimpleXMLRPCServer(("localhost", 8080))
server.register_function(getdirs)
server.serve_forever()
Now...this seems to run just fine on my red hat 9 machine. Problem is I
cant connect to it from another machine using the following code:
import xmlrpclib
client = xmlrpclib.Server("http://luna:8080")
print client.getdirs('/');
I get a connection refused error. Interestingly enough this works just
dandy if run on the same box as the server piece. Anyone have any
ideas what i need to do to get this to work? I run the java servlet
runner Resin on the box and that always seems to work just fine on the
same port.
thanks,
Jason
how to get the dir lists I want on my unix machine I want to turn the
same thing into an XML-RPC service. Using Simple XMLRPCServer.py I
created my own version by adding my getdirs function and then I call the
code to open the server:
import os
import os.path
import SimpleXMLRPCServer
import xmlrpclib
import SocketServer
import BaseHTTPServer
import sys
class SimpleXMLRPCRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_POST(self):
"""Handles the HTTP POST request.
Attempts to interpret all HTTP POST requests as XML-RPC calls,
which are forwarded to the _dispatch method for handling.
"""
try:
# get arguments
data = self.rfile.read(int(self.headers["content-length"]))
params, method = xmlrpclib.loads(data)
# generate response
try:
response = self._dispatch(method, params)
# wrap response in a singleton tuple
response = (response,)
except:
# report exception back to server
response = xmlrpclib.dumps(
xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type,
sys.exc_value))
)
else:
response = xmlrpclib.dumps(response, methodresponse=1)
except:
# internal error, report as HTTP server error
self.send_response(500)
self.end_headers()
else:
# got a valid XML RPC response
self.send_response(200)
self.send_header("Content-type", "text/xml")
self.send_header("Content-length", str(len(response)))
self.end_headers()
self.wfile.write(response)
# shut down the connection
self.wfile.flush()
self.connection.shutdown(1)
def _dispatch(self, method, params):
func = None
try:
# check to see if a matching function has been registered
func = self.server.funcs[method]
except KeyError:
if self.server.instance is not None:
# check for a _dispatch method
if hasattr(self.server.instance, '_dispatch'):
return self.server.instance._dispatch(method, params)
else:
# call instance method directly
try:
func = _resolve_dotted_attribute(
self.server.instance,
method
)
except AttributeError:
pass
if func is not None:
return apply(func, params)
else:
raise Exception('method "%s" is not supported' % method)
def log_request(self, code='-', size='-'):
"""Selectively log an accepted request."""
if self.server.logRequests:
BaseHTTPServer.BaseHTTPRequestHandler.log_request(self,
code, size)
def _resolve_dotted_attribute(obj, attr):
"""Resolves a dotted attribute name to an object. Raises
an AttributeError if any attribute in the chain starts with a '_'.
"""
for i in attr.split('.'):
if i.startswith('_'):
raise AttributeError(
'attempt to access private attribute "%s"' % i
)
else:
obj = getattr(obj,i)
return obj
class SimpleXMLRPCServer(SocketServer.TCPServer):
def __init__(self, addr, requestHandler=SimpleXMLRPCRequestHandler,
logRequests=1):
self.funcs = {}
self.logRequests = logRequests
self.instance = None
SocketServer.TCPServer.__init__(self, addr, requestHandler)
def register_instance(self, instance):
self.instance = instance
def register_function(self, function, name = None):
if name is None:
name = function.__name__
self.funcs[name] = function
def getdirs(path):
dirs=[]
for entry in os.listdir(path):
entry=os.path.join(path,entry)
if os.path.isdir(entry):
dirs.append(entry)
return dirs
server = SimpleXMLRPCServer(("localhost", 8080))
server.register_function(getdirs)
server.serve_forever()
Now...this seems to run just fine on my red hat 9 machine. Problem is I
cant connect to it from another machine using the following code:
import xmlrpclib
client = xmlrpclib.Server("http://luna:8080")
print client.getdirs('/');
I get a connection refused error. Interestingly enough this works just
dandy if run on the same box as the server piece. Anyone have any
ideas what i need to do to get this to work? I run the java servlet
runner Resin on the box and that always seems to work just fine on the
same port.
thanks,
Jason