"""SecureXMLRPCServer.py - simple XML RPC server supporting SSL. Based on this article: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81549 For windows users: http://webcleaner.sourceforge.net/pyOpenSSL-0.6.win32-py2.4.exe """ # Configure below LISTEN_HOST='127.0.0.1' # You should not use '' here, unless you have a real FQDN. LISTEN_PORT=443 KEYFILE='certs/saturnus.msnet.key.pem' # Replace with your PEM formatted key file CERTFILE='certs/saturnus.msnet.cert.pem' # Replace with your PEM formatted certificate file # Configure above import SocketServer import BaseHTTPServer import SimpleHTTPServer import SimpleXMLRPCServer import socket, os from OpenSSL import SSL class SecureXMLRPCServer(BaseHTTPServer.HTTPServer,SimpleXMLRPCServer.SimpleXMLRPCDispatcher): def __init__(self, server_address, HandlerClass, logRequests=True): """Secure XML-RPC server. It it very similar to SimpleXMLRPCServer but it uses HTTPS for transporting XML data. """ self.logRequests = logRequests SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self) SocketServer.BaseServer.__init__(self, server_address, HandlerClass) ctx = SSL.Context(SSL.SSLv23_METHOD) ctx.use_privatekey_file (KEYFILE) ctx.use_certificate_file(CERTFILE) self.socket = SSL.Connection(ctx, socket.socket(self.address_family, self.socket_type)) self.server_bind() self.server_activate() class SecureXMLRpcRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): """Secure XML-RPC request handler class. It it very similar to SimpleXMLRPCRequestHandler but it uses HTTPS for transporting XML data. """ def setup(self): self.connection = self.request self.rfile = socket._fileobject(self.request, "rb", self.rbufsize) self.wfile = socket._fileobject(self.request, "wb", self.wbufsize) def do_POST(self): """Handles the HTTPS POST request. It was copied out from SimpleXMLRPCServer.py and modified to shutdown the socket cleanly. """ try: # get arguments data = self.rfile.read(int(self.headers["content-length"])) # 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. response = self.server._marshaled_dispatch( data, getattr(self, '_dispatch', None) ) except: # This should only happen if the module is buggy # 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() # Modified here! def test(HandlerClass = SecureXMLRpcRequestHandler,ServerClass = SecureXMLRPCServer): """Test xml rpc over https server""" class xmlrpc_registers: def __init__(self): import string self.python_string = string def add(self, x, y): return x + y def mult(self,x,y): return x*y def div(self,x,y): return x//y server_address = (LISTEN_HOST, LISTEN_PORT) # (address, port) server = ServerClass(server_address, HandlerClass) server.register_instance(xmlrpc_registers()) sa = server.socket.getsockname() print "Serving HTTPS on", sa[0], "port", sa[1] server.serve_forever() if __name__ == '__main__': test() # Here is the client for testing: import xmlrpclib server = xmlrpclib.Server('https://localhost:443') print server.add(1,2) print server.div(10,4)