Python の xmlrpclib で proxy + Basic 認証
xmlrpclib を proxy 経由で使わなければいけなかったのだが、 xmlrpclib は httplib で通信をしているようで、環境変数の http_proxy を見てくれない。
色々とググってみても、 httplib をそのまま使って proxy を使う方法しか出てこなかった。
今回は proxy だけでなく Basic 認証も行わなければいけないので、なるべくなら urllib2 を使ってリクエストを送りたかった。
なので Transport クラスを継承して urllib2 を使ったリクエストを送るように書き換えてみた。
結果
で、できたのが以下のコード。
xmlrpclib.Transport を継承し、 Transport::request をオーバライドして urllib2 を使ってリクエストを送っている。
urllib2 のハンドラを使って
- xmlrpc
- proxy 経由のアクセス
- Basic 認証
ができるようになった。
必要あるのかどうなのかわからないけれど、 cookie も保存するようにしてみた。
#-*- coding:utf-8 -*- import cookielib import urllib2 import xmlrpclib class ProxiedTransport(xmlrpclib.Transport): SCHEME = 'https' def __init__(self, passwds, proxies=None, *args, **argd): ''' 初期化 ''' xmlrpclib.Transport.__init__(self, *args, **argd) handlers = [] # proxy handler を作る if proxies is not None: proxy = urllib2.ProxyHandler(proxies) handlers.append(proxy) # cookie processor も作る cj = cookielib.CookieJar() cjhdr = urllib2.HTTPCookieProcessor(cj) handlers.append(cjhdr) mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() for url, (usr, passwd) in passwds.iteritems(): mgr.add_password(None, url, usr, passwd) # Basic 認証 handler を作る basic = urllib2.HTTPBasicAuthHandler(mgr) handlers.append(basic) # opener を作る self.opener = urllib2.build_opener(*handlers) def request(self, host, handler, request_body, verbose=0): ''' opener を使って url を開く ''' self.verbose = 0 scheme = self.SCHEME url = '%(scheme)s://%(host)s%(handler)s' % locals() req = urllib2.Request(url, data=request_body, headers={'Content-Type':'text/xml'}) fp = self.opener.open(req) return self._parse_response(fp, None) def test(): url = 'https://xmlrpc.exsample.com/XML-RPC' usr = 'guest' passwd = 'guest' trans = ProxiedTransport({url:[usr, passwd]}, {'https':'http://proxy.example.com:8080/'}) proxy = xmlrpclib.ServerProxy(url, trans) arg1 = 10 arg2 = 'aaaa' print proxy.rpcCall(arg1, arg2) if __name__ == '__main__': test()