Solution for XML-RPC over a proxy



All,

I couldn't get my xml-rpc script to work via a corporate proxy.

I noticed a few posts asking about this, and a very good helper script by jjk on
starship. That script didn't work for me, and I think its a little old -- but it
was very helpful to figure it out.

The below script is a replacement/update to the earlier work. It is runnable as
a test or usable as a module. Tests pass from behind and away from a proxy, on
win32 and Linux i686, with Python 2.4.1.

Comments welcome.

Regards
Andrew

--- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8
#!/bin/env python
"""urllib2-based transport class for xmlrpclib.py (with test code).

Written from scratch but inspired by xmlrpc_urllib_transport.py
file from http://starship.python.net/crew/jjkunce/ by jjk.

A. Ellerton 2006-07-06

Testing with Python 2.4 on Windows and Linux, with/without a corporate
proxy in place.

****************************
*** USE AT YOUR OWN RISK ***
****************************
"""

import xmlrpclib

class ProxyTransport(xmlrpclib.Transport):
"""Provides an XMl-RPC transport routing via a http proxy.

This is done by using urllib2, which in turn uses the environment
varable http_proxy and whatever else it is built to use (e.g. the
windows registry).

NOTE: the environment variable http_proxy should be set correctly.
See checkProxySetting() below.

Written from scratch but inspired by xmlrpc_urllib_transport.py
file from http://starship.python.net/crew/jjkunce/ by jjk.

A. Ellerton 2006-07-06
"""

def request(self, host, handler, request_body, verbose):
import urllib2
self.verbose=verbose
url='http://'+host+handler
if self.verbose: "ProxyTransport URL: [%s]"%url

request = urllib2.Request(url)
request.add_data(request_body)
# Note: 'Host' and 'Content-Length' are added automatically
request.add_header("User-Agent", self.user_agent)
request.add_header("Content-Type", "text/xml") # Important

proxy_handler=urllib2.ProxyHandler()
opener=urllib2.build_opener(proxy_handler)
f=opener.open(request)
return(self.parse_response(f))


def checkProxySetting():
"""If the variable 'http_proxy' is set, it will most likely be in one
of these forms (not real host/ports):

proxyhost:8080
http://proxyhost:8080

urlllib2 seems to require it to have 'http;//" at the start.
This routine does that, and returns the transport for xmlrpc.
"""
import os, re
try:
http_proxy=os.environ['http_proxy']
except KeyError:
return

# ensure the proxy has the 'http://' at the start
#
match = re.match("(http://)?([-_\.A-Za-z]+):(\d+)", http_proxy)
if not match: raise Exception("Proxy format not recognised: [%s]" % http_proxy)
os.environ['http_proxy'] = "http://%s:%s"; % (match.group(2), match.group(3))
#print "Determined proxy: %s" % os.environ['http_proxy']
return


def test():
import sys, os

def nextArg():
try: return sys.argv.pop(1)
except: return None

checkProxySetting()

url=nextArg() or "http://betty.userland.com";
api=nextArg() or "examples.getStateName(32)" # "examples.getStateList([1,2])"
try:
server=xmlrpclib.Server(url, transport=ProxyTransport())
print "Url: %s" % url

try: print "Proxy: %s" % os.environ['http_proxy']
except KeyError: print "Proxy: (Apparently none)"

print "API: %s" % api
r = eval("server.%s"%api)
print "Result: ", r

except xmlrpclib.ProtocolError, e:
print "Connection error: %s" % e
except xmlrpclib.Fault, e:
print "Error: %s" % e

if __name__=='__main__':
# run with no parameters for basic test case.
test()
--- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8

.



Relevant Pages

  • Re: BSDstats v3.0 - The Security Rewrite
    ... Some sites require the use of a proxy for HTTP access. ... The bsdstats script could easily pick up that entry and set ... a management machine, and that management machine only has ...
    (freebsd-questions)
  • Re: BSDstats v3.0 - The Security Rewrite
    ... Seaman to come up with a more "security sensitive" version of BSDstats ... ... Some sites require the use of a proxy for HTTP access. ... The bsdstats script could easily pick up that entry and set ... a management machine, and that management machine only has ...
    (freebsd-questions)
  • Re: x.500 Addresses ?
    ... I wrote a script a few ... Function StampMembers (strGroupADsPath, dicSeenGroupMember) ... Currently we have Exchange Server 2003 SP1 servers in an AD forrest. ... Would a X.500 proxy address help, if so how do I do that? ...
    (microsoft.public.exchange.admin)
  • Re: Getting original working directory
    ... Also I do not agree that such thing is not possible because after python script finishes its work, it naturally gets back into the original location from where you started the script. ... Ensure your application has the right permissions to access the web service. ... "A GUID to to identify this rememberer" ... def get_proxy ...
    (comp.lang.python)
  • Re: How do I access a main frunction from an import module?
    ... def a: ... may/must call 0, 1, or many because blah blah blah ..." ... have Python ... script separate from each other, being that python is so flexible. ...
    (comp.lang.python)