[XML-SIG] Problem using xmlrpclib.

John J Lee jjl at pobox.com
Thu Aug 7 13:58:03 EDT 2003


On Wed, 6 Aug 2003, M.-A. Lemburg wrote:
[...]
> > access to a SalesForce.com server.  They supply both an XMLRPC and a SOAP
> > API.  They have a two step authentication process to get logged in, which
> > goes like this:
> >
> > 1.  Login using "https://www.salesforce.com/servlet/servlet.Api".
> >     - This returns the following XML fields:
> >             'userID':'<unique user ID>'
> >             'server_url': '<server to use for API transactions>'
> >             'session_id' : '<unique session ID>'
> >     - It also returns two "Set-Cookie" fields in the HTML headers (example
> > shown below, not a "real" session_id):
> >             header: Set-Cookie: sfdcweb=65.213.42.132.194511060194978591; path=/;
> > max-age=31536000
> >             header: Set-Cookie: sid=<ridiculously long session_id string>; path=/
[...]

Weird.  I suppose they have two separate systems working together, one of
which wants to maintain state via XML-RPC, and one via HTTP cookies.

If you reckon the cookies have some significant purpose, try my
ClientCookie library.  Briefly looking at xmlrpclib.py, it's easy to do.
You'd need to make your own Transport class to pass (an instance of) to
ServerProxy, and trivial Request and Response classes to keep ClientCookie
happy:

Subclass Transport (or write your class as a mixin, and subclass from both
Transport and SafeTransport).  Keep a Cookies object somewhere convenient.
Override the Transport.request method.  In that method, make a Request and
a Response object (see below).  Call cookies.add_cookie_header(request)
just before the self.send_content(...)  call, then send the headers:

for hdr, value in request.headers.items():
    h.putheader(hdr, value)

(you could stick all that in a send_cookies method, of course).

Call cookies.extract_cookies(request, response) just after the
h.getreply(...) call.  That should do the trick.

For your purposes, Response can just be:

class Response:
    def __init__(self, headers): self.headers = headers
    def info(self): return self.headers

and for Request, you can just borrow urllib2's Request object (the URL to
pass to Request constructor -- the only argument you need to bother with,
I think -- will just be "http://"+host+"/", I suppose).

HTH

BTW, use the latest alpha version of ClientCookie -- interface won't
change for this simple usage.  There is a known bug with proxies fixed
(and another whose nature I forget) in an unreleased version, mail me if
you run into trouble.


John




More information about the XML-SIG mailing list