#5 Cookie support

open
nobody
5
2004-11-17
2004-11-17
bostonaudi
No

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);

Discussion

  • bostonaudi

    bostonaudi - 2004-11-17

    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.

     
  • bostonaudi

    bostonaudi - 2004-11-17
     
  • Nobody/Anonymous

    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

     

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks