views:

34

answers:

3

Because cross-domain xmlrpc requests are not possible in JavaScript I need to create a Python app which exposes both some HTML through HTTP and an XML-RPC service on the same domain.

Creating an HTTP request handler and SimpleXMLRPCServer in python is quite easy, but they both have to listen on a different port, which means a different domain.

Is there a way to create something that will listen on a single port on the localhost and expose both the HTTPRequestHandler and XMLRPCRequest handler?

Right now I have two different services:

httpServer = HTTPServer(('localhost',8001), HttpHandler);
xmlRpcServer = SimpleXMLRPCServer(('localhost',8000),requestHandler=RequestHandler)

Update

  • I cannot install Apache on the device
  • The hosted page will be a single html page
  • The only client will be the device on witch the python service runs itself
A: 

Using HTTPServer for providing contents is not a good idea. You should use a webserver like Apache and use Python as CGI (or a more advanced interface like mod_wsgi).

Then, the webserver is running on one port and you can server HTML directly over the webserver and write as many CGI scripts as you like in Python, as example one for XMLRPC requests using CGIXMLRPCRequestHandler.

class MyFuncs:
    def div(self, x, y) : return x // y


handler = CGIXMLRPCRequestHandler()
handler.register_function(pow)
handler.register_function(lambda x,y: x+y, 'add')
handler.register_introspection_functions()
handler.register_instance(MyFuncs())
handler.handle_request()
leoluk
Problem is I cannot install apache on the target device (being a restricted apple device :p)
TimothyP
+1  A: 

Both of them subclass of SocketServer.TCPServer. There must be someway to refactor them so that once server instance can dispatch to both.

An easier alternative may be to keep the HTTPServer in front and proxy XML RPC to the SimpleXMLRPCServer instance.

Wai Yip Tung
This has helped me find my solutions
TimothyP
A: 

The solution was actually quite simple, based on Wai Yip Tung's reply:

All I had to do was keep using the SimpleXMLRPCServer instance, but modify the handler:

class RequestHandler(SimpleXMLRPCRequestHandler):
    rpc_paths = ('/RPC2',)

    def do_GET(self):
          #implementation here

This will cause the handler to respond to GET requests as well as the original POST (XML-RPC) requests.

TimothyP