Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Empty cookiejar using SUDS

I'm running SUDS 0.4 on Linux Slackware 13.0 with python 2.6.2. When I call SOAP method using this code:

from suds.client import Client

client = Client(url='file:acctWeb.wsdl',
                location='http://10.242.69.4:8088/pfmaccess')

res = client.service.login(login='user',password='passwd')

I receive following response:

DEBUG:suds.transport.http:received:
CODE: 200
HEADERS: {'set-cookie': 'OSP_Ref=0000000573800052;Domain=10.242.69.4:8088;Path=/pfmaccess', 'content-length': '26541', 'content-type': 'text/xml; charset=utf-8', 'connection': 'close', 'server': 'Alcatel-Lucent OSP 2.4'}

but

>>> client.options.transport.cookiejar
<cookielib.CookieJar[]>

shows that there are no cookies available. What could be a reason for that? I'm not able to use SOAP API because I need to pass credentials sent in response cookie.

Please help me on this.

BR

rjan

like image 614
rjan Avatar asked Jan 19 '12 14:01

rjan


1 Answers

Ok, i've played around a bit with it.

first, a little test server (courtesy of soaplib):

import soaplib
from soaplib.core.service import rpc, DefinitionBase, soap
from soaplib.core.model.primitive import String, Integer
from soaplib.core.server import wsgi
from soaplib.core.model.clazz import Array
import sys, pprint

class HelloWorldService(DefinitionBase):
    @soap(String,Integer,_returns=Array(String))
    def say_hello(self,name,times):
        results = []
        for i in range(0,times):
            results.append('Hello, %s'%name)
        return results

class WsgiApp(wsgi.Application):

    def on_wsgi_return(self, env, headers, return_str):
        headers['Set-Cookie'] = 'spam=eggs;domain=127.0.0.1;path=/'
        print >>sys.stderr, headers

if __name__=='__main__':
    try:
        from wsgiref.simple_server import make_server
        soap_application = soaplib.core.Application([HelloWorldService], 'tns')
        wsgi_application = WsgiApp(soap_application)
        server = make_server('localhost', 7789, wsgi_application)
        server.serve_forever()
    except ImportError:
        print "Error: example server code requires Python >= 2.5"

with some little modification to set a cookie header.

and a suds-testclient:

from suds import client, transport

c = client.Client("http://127.0.0.1:7789/?wsdl")
print c.service.say_hello("spam", 1)
print c.options.transport.cookiejar

running this produces:

(stringArray){
   string[] = 
      "Hello, spam",
 }
<cookielib.CookieJar[<Cookie spam=eggs for .127.0.0.1/>]>

so it seams to work. but if you change the request url to http://localhost:7789/?wsdl you'll get:

(stringArray){
   string[] = 
      "Hello, spam",
 }
<cookielib.CookieJar[]>

turning on some logging for cookielib at the client...

import logging
import cookielib
logging.basicConfig()
logging.getLogger('cookielib').setLevel(logging.DEBUG)
cookielib.debug = True

... and it reveals reveals why:

DEBUG:cookielib:add_cookie_header
DEBUG:cookielib:extract_cookies: Date: Thu, 17 May 2012 15:56:01 GMT
Server: WSGIServer/0.1 Python/2.7.3
Set-Cookie: spam=eggs;domain=127.0.0.1;path=/
Content-Length: 822
Content-Type: text/xml

DEBUG:cookielib: - checking cookie spam=eggs
DEBUG:cookielib:   effective request-host localhost.local (even with added initial
                   dot) does not end with .127.0.0.1
(stringArray){
   string[] = 
      "Hello, spam",
 }
<cookielib.CookieJar[]>

the simple explanation is: the cookie domain does not match the request's server domain, and as it seems cookielib does not do any lookup when verifying the domain.

so the solution would be one of:

  • make sure client and server use the same domain (either domainname or IP)
    in the example i have to set both to localhost.local to make it work (may depend on the hosts file...)
  • remove the domain from the sent cookie, then cookieib uses the request domain automatically
  • implement a cookiejar that uses DNS lookups

Oh, and last but not least: the reason why it didn't work in the OPs question:
the port is not part of the domain, therfore a cookie with Domain=10.242.69.4:8088 will always be rejected.

like image 93
mata Avatar answered Oct 11 '22 01:10

mata