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 SimpleXMLRPCSer ver
import xmlrpclib
import SocketServer
import BaseHTTPServer
import sys
class SimpleXMLRPCReq uestHandler(Bas eHTTPServer.Bas eHTTPRequestHan dler):
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.heade rs["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_respo nse(500)
self.end_header s()
else:
# got a valid XML RPC response
self.send_respo nse(200)
self.send_heade r("Content-type", "text/xml")
self.send_heade r("Content-length", str(len(respons e)))
self.end_header s()
self.wfile.writ e(response)
# shut down the connection
self.wfile.flus h()
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.fun cs[method]
except KeyError:
if self.server.ins tance is not None:
# check for a _dispatch method
if hasattr(self.se rver.instance, '_dispatch'):
return self.server.ins tance._dispatch (method, params)
else:
# call instance method directly
try:
func = _resolve_dotted _attribute(
self.server.ins tance,
method
)
except AttributeError:
pass
if func is not None:
return apply(func, params)
else:
raise Exception('meth od "%s" is not supported' % method)
def log_request(sel f, code='-', size='-'):
"""Selectiv ely log an accepted request."""
if self.server.log Requests:
BaseHTTPServer. BaseHTTPRequest Handler.log_req uest(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 SimpleXMLRPCSer ver(SocketServe r.TCPServer):
def __init__(self, addr, requestHandler= SimpleXMLRPCReq uestHandler,
logRequests=1):
self.funcs = {}
self.logRequest s = logRequests
self.instance = None
SocketServer.TC PServer.__init_ _(self, addr, requestHandler)
def register_instan ce(self, instance):
self.instance = instance
def register_functi on(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.j oin(path,entry)
if os.path.isdir(e ntry):
dirs.append(ent ry)
return dirs
server = SimpleXMLRPCSer ver(("localhost ", 8080))
server.register _function(getdi rs)
server.serve_fo rever()
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.Serve r("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 SimpleXMLRPCSer ver
import xmlrpclib
import SocketServer
import BaseHTTPServer
import sys
class SimpleXMLRPCReq uestHandler(Bas eHTTPServer.Bas eHTTPRequestHan dler):
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.heade rs["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_respo nse(500)
self.end_header s()
else:
# got a valid XML RPC response
self.send_respo nse(200)
self.send_heade r("Content-type", "text/xml")
self.send_heade r("Content-length", str(len(respons e)))
self.end_header s()
self.wfile.writ e(response)
# shut down the connection
self.wfile.flus h()
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.fun cs[method]
except KeyError:
if self.server.ins tance is not None:
# check for a _dispatch method
if hasattr(self.se rver.instance, '_dispatch'):
return self.server.ins tance._dispatch (method, params)
else:
# call instance method directly
try:
func = _resolve_dotted _attribute(
self.server.ins tance,
method
)
except AttributeError:
pass
if func is not None:
return apply(func, params)
else:
raise Exception('meth od "%s" is not supported' % method)
def log_request(sel f, code='-', size='-'):
"""Selectiv ely log an accepted request."""
if self.server.log Requests:
BaseHTTPServer. BaseHTTPRequest Handler.log_req uest(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 SimpleXMLRPCSer ver(SocketServe r.TCPServer):
def __init__(self, addr, requestHandler= SimpleXMLRPCReq uestHandler,
logRequests=1):
self.funcs = {}
self.logRequest s = logRequests
self.instance = None
SocketServer.TC PServer.__init_ _(self, addr, requestHandler)
def register_instan ce(self, instance):
self.instance = instance
def register_functi on(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.j oin(path,entry)
if os.path.isdir(e ntry):
dirs.append(ent ry)
return dirs
server = SimpleXMLRPCSer ver(("localhost ", 8080))
server.register _function(getdi rs)
server.serve_fo rever()
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.Serve r("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