boriel.com

Hacks, science and curiosities

XML-RPC over a proxy server

– 🕓 1 min read

I had been looking for a way to call a function using XML-RPC in Python with the xmlrpclib class. The problem was I wanted to call it from within an organization behind an HTTP proxy, and the python object (ServerProxy) didn't allow it by default.

Nevertheless, if we look closer to the class constructor:

class ServerProxy( uri[, transport[, encoding[, verbose[, allow_none]]]]) 

we realize it's possible to define an optional Transport object. And that was the solution, as I found explained in this (Japanese) page: XML-RPC over the proxy server. Link is broken, but there is already an example in the python official documentation.

It defines a child transport class:

import xmlrpclib

class ProxiedTransport(xmlrpclib.Transport):
    # Put here an identification string for your application
    user_agent = 'hogehoge'

    def set_proxy(self, proxy):
        self.proxy = proxy

    def make_connection(self, host):
        self.realhost = host
        import httplib
        return httplib.HTTPConnection(self.proxy)

    def send_request(self, connection, handler, request_body):
        connection.putrequest("POST", 'http://%s%s' % (self.realhost, handler))

    def send_host(self, connection, host):
        connection.putheader('Host', self.realhost)

    def __init__(self, proxy, use_datetime = 0): 
        xmlrpclib.Transport.__init__(self, use_datetime)
        self.set_proxy(proxy)

And now it's possible to do XML-RPC over a proxy:

# Creates the XML-RPC server connection
server = xmlrpclib.ServerProxy('http://xmlrpc-c.sourceforge.net/api/sample.php',
  transport = ProxiedTransport('proxy.server:3128')

# Lists remote server exported methods
for method in server.system.listMethods():
  print method, server.system.methodHelp(method)