Python XML RPC over HTTP proxy

2012-05-09 00:00:00 +0100


The XML-RPC over HTTP proxy given in Python documentation doesn’t really work, so I’ve written a fixed XML-RPC transport for xmlrpclib that seems to work. The reference version didn’t work for a few reasons — seemingly there were internal API changes. Also it didn’t send Content-Length that was required by some servers.

The syntax is for Python 3. To use with Python 2 you need to change xmlrpc.client to xmlrpclib and http.client to httplib.

import xmlrpc.client import http.client

PROXY_HOST = ‘proxy.example.com’ PROXY_PORT = 3128

class ProxiedTransport(xmlrpc.client.Transport): def init(self, proxy_host, proxy_port, use_datetime=False): self.proxy_host = proxy_host self.proxy_port = proxy_port self._connection = (None, None) self._use_datetime = use_datetime def send_request(self, host, handler, request_body, verbose=True): print(request_body) connection = self.make_connection(host) uri = ‘http://{0}{1}’.format(host, handler) print(uri) connection.putrequest(“POST”, uri) connection.putheader(“Content-Type”, “text/xml”) connection.putheader(“Content-Length”, len(request_body)) connection.putheader(“User-Agent”, “xmlrpclib”) connection.endheaders() connection.send(request_body) return connection def make_connection(self, host): if self._connection and host == self._connection[0]: return self._connection[1] self._connection = host, http.client.HTTPConnection(self.proxy_host, self.proxy_port) return self._connection[1]

if name == “main”: p = ProxiedTransport(PROXY_HOST, PROXY_PORT) server = xmlrpc.client.ServerProxy(‘http://www.cookcomputing.com/xmlrpcsamples/RPC2.ashx’, transport=p) ret = server.system.listMethods() print(ret) ret = server.examples.getStateName(1) print(ret) </code>

Note that the XML-RPC service used in this example is real and live (as of May 2012), courtesy of Cook Computing. It’s great for testing, especially that it supports service enumeration (listMethods).