This extension to xmlrpclib allows us to maintain a session with a JSP server, so that there appears to be a stateful session. It tries to maintain the JSESSIONID call between calls to the server.
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | """A little Transport layer to maintain the JSESSIONID cookie that
Javaserver pages use to maintain a session. I'd like to use this
to make xmlrpclib session aware.
Sample usage:
server = Server("http://foobar.com/baz/servlet/xmlrpc.class")
print server.get_jsession_id();
print server.test.sayHello()
print server.get_jsession_id();
print server.test.sayGoodbye()
print server.get_jsession_id();
"""
import xmlrpclib
import Cookie
class JspAuthTransport(xmlrpclib.Transport):
def __init__(self):
self.__cookies = Cookie.SmartCookie()
def request(self, host, handler, request_body, verbose=0):
# issue XML-RPC request
h = self.make_connection(host)
if verbose:
h.set_debuglevel(1)
self.send_request(h, handler, request_body)
self.__sendJsessionCookie(h)
self.send_host(h, host)
self.send_user_agent(h)
self.send_content(h, request_body)
errcode, errmsg, headers = h.getreply()
if errcode != 200:
raise xmlrpclib.ProtocolError(
host + handler,
errcode, errmsg,
headers
)
self.verbose = verbose
self.__processCookies(headers)
return self.parse_response(h.getfile())
def get_jsession_id(self):
if self.__cookies.has_key('JSESSIONID'):
return self.__cookies['JSESSIONID'].value
return None
def __sendJsessionCookie(self, connection):
if self.__cookies.has_key('JSESSIONID'):
connection.putheader('Cookie', '$Version="1"; JSESSIONID=%s'
% self.get_jsession_id())
def __processCookies(self, headers):
if headers.getheader('Set-Cookie'):
self.__cookies.load(headers.getheader('Set-Cookie'))
def send_content(self, connection, request_body):
connection.putheader("Content-Type", "text/xml")
connection.putheader("Content-Length", str(len(request_body)))
connection.endheaders()
if request_body:
connection.send(request_body)
class Server:
"""A little wrapper to keep the transport and serverproxy together."""
def __init__(self, uri):
self.transport = JspAuthTransport()
self.serverproxy = xmlrpclib.ServerProxy(uri, self.transport)
def __getattr__(self, attr):
return getattr(self.serverproxy, attr)
def get_jsession_id(self):
return self.transport.get_jsession_id()
def _test2():
server = Server("http://www.oreillynet.com/meerkat/xml-rpc/server.php")
print server.system.listMethods()
if __name__ == '__main__':
_test2()
|
This code is not original. grin It's very similar to Amos's code that hacks Zope authentication into xmlrpc at:
http://www.zope.org/Members/Amos/XML-RPC
there's some dead code in there. Ooops. I just noticed that I left some dead code: the send_content() function of that transport subclass should be omitted. Sorry about that!