使用SUDS清空cookiejar
我在Linux Slackware 13.0上运行SUDS 0.4,使用的是python 2.6.2。当我用以下代码调用SOAP方法时:
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')
我收到了以下响应:
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'}
但是
>>> client.options.transport.cookiejar
<cookielib.CookieJar[]>
显示没有可用的cookies。这可能是什么原因呢?我无法使用SOAP API,因为我需要在响应的cookie中传递凭证。
请帮我解决这个问题。
祝好
rjan
1 个回答
7
好的,我稍微玩了一下这个东西。
首先,这是一个小测试服务器(感谢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"
我做了一些小修改来设置一个cookie头。
还有一个suds测试客户端:
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
运行这个会产生:
(stringArray){
string[] =
"Hello, spam",
}
<cookielib.CookieJar[<Cookie spam=eggs for .127.0.0.1/>]>
看起来是可以工作的。但是如果你把请求的地址改成 http://localhost:7789/?wsdl
,你会得到:
(stringArray){
string[] =
"Hello, spam",
}
<cookielib.CookieJar[]>
在客户端开启一些cookielib
的日志...
import logging
import cookielib
logging.basicConfig()
logging.getLogger('cookielib').setLevel(logging.DEBUG)
cookielib.debug = True
...这就揭示了原因:
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[]>
简单来说,就是:cookie的域名和请求的服务器域名不匹配,而且看起来cookielib
在验证域名时并没有进行任何查找。
所以解决办法可以是:
- 确保客户端和服务器使用相同的域名(可以是域名或IP)
在这个例子中,我需要把两者都设置为localhost.local
才能正常工作(可能还和hosts
文件有关...) - 从发送的cookie中去掉域名,这样
cookielib
会自动使用请求的域名 - 实现一个使用DNS查找的cookiejar
哦,最后但同样重要的是:OP问题中之所以不工作的原因是:
端口不是域名的一部分,因此一个带有Domain=10.242.69.4:8088
的cookie会始终被拒绝。