Add support to handle cookies coming from server. Perl's
Soap Lite makes this pretty simple with the transport
method. One simply creates a cookie object and passes
it to the transport method of the proxy object.
Example:
my $cookies = HTTP::Cookies->new(
ignore_discard =>1);
my $test = SOAP::Lite
-> uri('Namespace')
-> proxy('http://localhost:xxxx');
#set the cookies on the soap connection so that cookie
# information is sent across when the client connects to
# the server.
$test->transport->cookie_jar($cookies);
Logged In: YES
user_id=1161129
Note that I've attached client.py from the soappy lib with a
quick hack that basically now supports grabbing and sending
back cookies over SOAP.
Logged In: NO
if you use this class it works also.
from SOAPpy.Client import HTTPTransport
from SOAPpy.Client import *
from pprint import pprint
class Transport (HTTPTransport):
def __init__(self):
self.__cookies = []
def call(self, addr, data, namespace, soapaction = None,
encoding = None,
http_proxy = None, config = Config):
import httplib
if not isinstance(addr, SOAPAddress):
addr = SOAPAddress(addr, config)
# Build a request
if http_proxy:
real_addr = http_proxy
real_path = addr.proto + "://" + addr.host +
addr.path
else:
real_addr = addr.host
real_path = addr.path
if addr.proto == 'httpg':
from pyGlobus.io import GSIHTTP
r = GSIHTTP(real_addr, tcpAttr = config.tcpAttr)
elif addr.proto == 'https':
r = httplib.HTTPS(real_addr)
else:
r = httplib.HTTP(real_addr)
r.putrequest("POST", real_path)
r.putheader("Host", addr.host)
r.putheader("User-agent", SOAPUserAgent())
t = 'text/xml';
if encoding != None:
t += '; charset="%s"' % encoding
r.putheader("Content-type", t)
r.putheader("Content-length", str(len(data)))
#####################
# cookie to set
#####################
[r.putheader ("cookie", cook) for cook in
self.__cookies]
# if user is not a user:passwd format
# we'll receive a failure from the server. . .I
guess (??)
if addr.user != None:
val = base64.encodestring(addr.user)
r.putheader('Authorization','Basic ' +
val.replace('\012',''))
# This fixes sending either "" or "None"
if soapaction == None or len(soapaction) == 0:
r.putheader("SOAPAction", "")
else:
r.putheader("SOAPAction", '"%s"' % soapaction)
if config.dumpHeadersOut:
s = 'Outgoing HTTP headers'
debugHeader(s)
print "POST %s %s" % (real_path, r._http_vsn_str)
print "Host:", addr.host
print "User-agent: SOAPpy " + __version__ + "
(http://pywebsvcs.sf.net)"
print "Content-type:", t
print "Content-length:", len(data)
print 'SOAPAction: "%s"' % soapaction
debugFooter(s)
r.endheaders()
if config.dumpSOAPOut:
s = 'Outgoing SOAP'
debugHeader(s)
print data,
if data[-1] != '\n':
print
debugFooter(s)
#######################################
# send the payload
#######################################
r.send(data)
# read response line
code, msg, headers = r.getreply()
###################
# Cookies to set
###################
if headers:
hs = headers.get("Set-Cookie")
if hs :
[self.__cookies.append (s) for s in
hs.splitlines ()]
if headers:
content_type =
headers.get("content-type","text/xml")
content_length = headers.get("Content-length")
else:
content_type=None
content_length=None
# work around OC4J bug which does '<len>, <len>' for
some reaason
if content_length:
comma=content_length.find(',')
if comma>0:
content_length = content_length[:comma]
# attempt to extract integer message size
try:
message_len = int(content_length)
except:
message_len = -1
if message_len < 0:
# Content-Length missing or invalid; just read
the whole socket
# This won't work with HTTP/1.1 chunked encoding
data = r.getfile().read()
message_len = len(data)
else:
data = r.getfile().read(message_len)
if(config.debug):
print "code=",code
print "msg=", msg
print "headers=", headers
print "content-type=", content_type
print "data=", data
if config.dumpHeadersIn:
s = 'Incoming HTTP headers'
debugHeader(s)
if headers.headers:
print "HTTP/1.? %d %s" % (code, msg)
print "\n".join(map (lambda x: x.strip(),
headers.headers))
else:
print "HTTP/0.9 %d %s" % (code, msg)
debugFooter(s)
def startswith(string, val):
return string[0:len(val)] == val
if code == 500 and not \ ( startswith(content_type, "text/xml") and
message_len > 0 ):
raise HTTPError(code, msg)
if config.dumpSOAPIn:
s = 'Incoming SOAP'
debugHeader(s)
print data,
if (len(data)>0) and (data[-1] != '\n'):
print
debugFooter(s)
if code not in (200, 500):
raise HTTPError(code, msg)
# get the new namespace
if namespace is None:
new_ns = None
else:
new_ns = self.getNS(namespace, data)
# return response payload
return data, new_ns