mvantellingen / python-zeep

A Python SOAP client
http://docs.python-zeep.org
Other
1.88k stars 578 forks source link

SoapMessage.parse changes to handle indirect soap:body and soap:header elements #1289

Open Hatell opened 2 years ago

Hatell commented 2 years ago

There is a parsing issue if an operation output/input does not have direct children soap:body or soap:header elements. Here is a sample zipped WSDL file attached where a getWsdl-operation have a direct child mime:multipartRelated in a wsdl:output element.

    <wsdl:operation name="getWsdl">
      <soap:operation soapAction=""/>
      <wsdl:input name="getWsdl">
        <soap:body parts="getWsdl" use="literal"/>
        <soap:header message="xrd:getWsdl" part="client" use="literal"/>
        <soap:header message="xrd:getWsdl" part="service" use="literal"/>
        <soap:header message="xrd:getWsdl" part="userId" use="literal"/>
        <soap:header message="xrd:getWsdl" part="id" use="literal"/>
        <soap:header message="xrd:getWsdl" part="protocolVersion" use="literal"/>
      </wsdl:input>
      <wsdl:output name="getWsdlResponse">
        <mime:multipartRelated>
          <mime:part>
            <soap:body parts="getWsdlResponse" use="literal"/>
            <soap:header message="xrd:getWsdlResponse" part="client" use="literal"/>
            <soap:header message="xrd:getWsdlResponse" part="service" use="literal"/>
            <soap:header message="xrd:getWsdlResponse" part="userId" use="literal"/>
            <soap:header message="xrd:getWsdlResponse" part="id" use="literal"/>
            <soap:header message="xrd:getWsdlResponse" part="protocolVersion" use="literal"/>
          </mime:part>
          <mime:part>
            <mime:content part="wsdl" type="text/xml"/>
          </mime:part>
        </mime:multipartRelated>
      </wsdl:output>
    </wsdl:operation>

xroad_meta_service.zip

The issue is that those soap:body and soap:header elements in wsdl:output are not found and therefore not parsed. When request is done then response processing fails and raises AttributeError.

Traceback (most recent call last):
  File "/home/user/git/xroad/client.py", line 132, in <module>
    res = client.service.getWsdl(
  File "/home/user/.virtualenvs/zeep/lib64/python3.10/site-packages/zeep/proxy.py", line 46, in __call__
    return self._proxy._binding.send(
  File "/home/user/.virtualenvs/zeep/lib64/python3.10/site-packages/zeep/wsdl/bindings/soap.py", line 135, in send
    return self.process_reply(client, operation_obj, response)
  File "/home/user/.virtualenvs/zeep/lib64/python3.10/site-packages/zeep/wsdl/bindings/soap.py", line 231, in process_reply
    result = operation.process_reply(doc)
  File "/home/user/.virtualenvs/zeep/lib64/python3.10/site-packages/zeep/wsdl/bindings/soap.py", line 430, in process_reply
    return self.output.deserialize(envelope)
  File "/home/user/.virtualenvs/zeep/lib64/python3.10/site-packages/zeep/wsdl/messages/soap.py", line 101, in deserialize
    body_result = self._deserialize_body(body)
  File "/home/user/.virtualenvs/zeep/lib64/python3.10/site-packages/zeep/wsdl/messages/soap.py", line 442, in _deserialize_body
    result = self.body.parse(xmlelement, self.wsdl.types, context=context)
AttributeError: 'NoneType' object has no attribute 'parse'

I changed find and findall to look elements anywhere from given tree.