Welcome, guest | Sign In | My Account | Store | Cart

To access an XML-RPC server through a proxy which requires authentication, you need to define a custom transport. the custom transport mentioned in the python docs, allows only proxy server's which do not require authentication. (http://docs.python.org/lib/xmlrpc-client-example.html). Have tried to use urllib which has support for proxy server and added the headers required for authentication. Idea to use urllib was taken from this thread (http://mail.python.org/pipermail/python-list/2001-July/098183.html)

Python, 42 lines
 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
import base64
import urllib
from urllib import unquote, splittype, splithost
import xmlrpclib

class UrllibTransport(xmlrpclib.Transport):
    def set_proxy(self, proxy):
        self.proxyurl = proxy
                
    def request(self, host, handler, request_body, verbose=0):
        type, r_type = splittype(self.proxyurl)
        phost, XXX = splithost(r_type)

        puser_pass = None
        if '@' in phost:
            user_pass, phost = phost.split('@', 1)
            if ':' in user_pass:
                user, password = user_pass.split(':', 1)
                puser_pass = base64.encodestring('%s:%s' % (unquote(user),
                                                unquote(password))).strip()
        
        urlopener = urllib.FancyURLopener({'http':'http://%s'%phost})
        if not puser_pass:
            urlopener.addheaders = [('User-agent', self.user_agent)]
        else:
            urlopener.addheaders = [('User-agent', self.user_agent),
                                    ('Proxy-authorization', 'Basic ' + puser_pass) ]

        host = unquote(host)
        f = urlopener.open("http://%s%s"%(host,handler), request_body)

        self.verbose = verbose 
        return self.parse_response(f)
        
if __name__ == '__main__':
    proxy = "http://proxy_user:proxy_passwd@my.authenticated.proxy.server:8080"
    
    p = UrllibTransport()
    p.set_proxy(proxy)
    
    server = xmlrpclib.Server("http://time.xmlrpc.com/RPC2", transport=p)
    print server.currentTime.getCurrentTime()

1 comment

suresh babu 12 years, 6 months ago  # | flag

Hi, This works perfectly fine for HTTP xml-rpc servers, but not for HTTPS servers. Is there a solution for HTTPS servers?

Thanks