2011-01-05 56 views
2

当我尝试执行此代码:创建无效SUDS信封

mmurl = 'http://server/_mmwebext/mmwebext.dll?WSDL?server=localhost' 
mmclient = Client(mmurl, plugins=[EnvelopeFixer()]) 
loginResult = mmclient.service[1].Login(u'localhost', u'user', u'pass') 

以下信封:

<SOAP-ENV:Envelope xmlns:ns0="http://menandmice.com/webservices/" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
    <SOAP-ENV:Header/> 
    <ns1:Body> 
     <ns0:Login> 
     <ns0:server>localhost</ns0:server> 
     <ns0:loginName>user</ns0:loginName> 
     <ns0:password>pass</ns0:password> 
     </ns0:Login> 
    </ns1:Body> 
</SOAP-ENV:Envelope> 

返回:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <SOAP-ENV:Body> 
     <SOAP-ENV:Fault> 
     <faultcode>SOAP-ENV:Client</faultcode> 
     <faultstring>Invalid command.</faultstring> 
     <detail> 
      <mmfaultdetails> 
       <message>Invalid command.</message> 
       <errorcode>5001</errorcode> 
      </mmfaultdetails> 
     </detail> 
     </SOAP-ENV:Fault> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

,但如果我改变它在soapUI至

<SOAP-ENV:Envelope xmlns:ns0="http://menandmice.com/webservices/" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
    <SOAP-ENV:Header/> 
    <SOAP-ENV:Body> 
     <ns0:Login> 
     <ns0:server>localhost</ns0:server> 
     <ns0:loginName>user</ns0:loginName> 
     <ns0:password>pass</ns0:password> 
     </ns0:Login> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

它成功返回

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <SOAP-ENV:Body> 
     <LoginResponse xmlns="http://menandmice.com/webservices/"> 
     <session>UEk6A0UC5bRJ92MqeLiU</session> 
     </LoginResponse> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

所以我的问题是我可以迫使泡沫创造body标签作为<SOAP-ENV:Body>代替<ns1:Body>或者是

我尝试这样做,看看是否我可以改变发送过来的XML线和使用wireshark嗅探流量,事实证明,它并没有改变发送的消息。发送方法被称为是肯定的,因为我看到打印出来的控制台

class EnvelopeFixer(MessagePlugin): 
    def sending(self, context): 
     # context is the envelope text 
     print type(context) 
     context.envelope = context.envelope.upper() 
     print context.envelope 

     return context 

我改变EnvelopeFixer使用编组,而不是发送,这似乎已经完成了招

class EnvelopeFixer(MessagePlugin): 

    def marshalled(self, context): 
     root = context.envelope.getRoot() 
     envelope = root.getChild("Envelope") 
     envelope.getChildren()[1].setPrefix("SOAP-ENV") 
     print envelope.getChildren()[1] 

     return context 

所以现在我已经更改了body元素的前缀以符合服务器的要求。喜悦!

+0

嗨davideagle,我用你的文章来修改我自己的标题。但是我将suds设置为suds.client的调试模式,我发现虽然上下文根据我的需要而改变。但是泡沫仍在发送之前的内容。你可以帮我吗? – 2014-01-24 07:39:00

+0

在运行setup.py build和setup.py之前,您是否删除了以前的egg文件? – davideagle 2014-01-24 13:59:57

+0

为什么我需要这样做?我使用的是'virtualenv',然后是'pip安装泡沫' – 2014-01-25 06:12:42

回答

3

令人遗憾的是RPC端点不能正确解析XML。一种解决方法是在发送前编辑信封的Client()中添加一个插件。 A MessagePlugin使您有机会在发送前修改suds.sax.document.Document或消息文本。

from suds.plugin import MessagePlugin 
class EnvelopeFixer(MessagePlugin): 
    def sending(self, context): 
     # context is the envelope text 
     context.envelope = context.envelope.upper() 
     return context 

client = Client(..., plugins=[EnvelopeFixer()]) 
+0

在发送方法上下文似乎不是文本,而是类型suds.plugin.MessageContext,所以我无法至少直接访问xml字符串 – davideagle 2011-01-06 14:44:22

+0

我使用的是suds 0.4.0。这个插件在这里被调用:https://fedorahosted.org/suds/browser/trunk/suds/client.py#L635 – joeforker 2011-01-06 15:15:12

+0

我给了这个镜头,并用wireshark查看实际的消息,但事实证明它并没有改变当我做context.envelope = context.envelope.upper() – davideagle 2011-01-06 15:46:15