Simple program that demonstrates how to write an XMLRCP server that uses https for transporting XML data.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | """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)
|
I was looking for a simple solution that combines secure connections with XML rpc but I could not find one. After some hours of programming, I could combine the example HTTPS server code with an XML RPC example, and here is the result. I think this is the easiest way, maybe not. :-)
See also: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81549
Fix for Python 2.5.
has changed to:
in Python 2.5. The following code should take care of it
Creating example self-signed certificates. This page provides with an easy example on how to create a key and a self-signed certificate.
http://panoptic.com/wiki/aolserver/How_to_generate_self-signed_SSL_certificates