2015-02-06 50 views
2

我在Hacklang中創建Soap Web服務,並在做一些測試時發現,在某些情況下,我收到SoapFault - Bad Request。爲了找出問題所在,我在php中編寫了簡化的類並準備了適當的wsdl文件。經過一些測試後,我發現在純非hhvm php中,它運行良好,但是當我在hhvm上運行它時,它無法按預期工作 - 對於某些請求它的工作原理,對於其他(僅有一點不同)它會拋出SoapFault 。HHVM上的SoapServer會拋出「Bad Request」SoapFault

soap.php:

<?php 

if (isset($_GET['wsdl'])) { 
    header('Content-Type:application/xml'); 
    echo file_get_contents('soap.wsdl'); 
    exit(0); 
} 

class WebService { 

    public function addContacts($addContactsRequest) { 
     return new \SoapVar(
      array(
       'status'  => 0, 
       'contactsCount' => 4, 
      ), 
      constant('SOAP_ENC_OBJECT'), 
      'AddContactsResponse', 
      'https://example.com/api/soap/' 
     ); 
    } 

} 

$server = new \SoapServer('soap.wsdl'); 
$server->setClass('WebService'); 
$server->handle(); 

soap.wsdl的:

<wsdl:definitions xmlns:tns="https://example.com/api/soap/" targetNamespace="https://example.com/api/soap/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"> 
    <wsdl:types> 
     <s:schema targetNamespace="https://example.com/api/soap/"> 
      <s:complexType name="AddContactsRequest"> 
       <s:sequence> 
        <s:element minOccurs="1" maxOccurs="1" nillable="false" name="contacts" type="tns:ContactArray"> 
        </s:element> 
        <s:element minOccurs="1" maxOccurs="1" nillable="true" name="groups" type="tns:stringArray"> 
        </s:element> 
        <s:element minOccurs="1" maxOccurs="1" nillable="true" name="createGroupsIfNotExist" type="s:boolean"> 
        </s:element> 
       </s:sequence> 
      </s:complexType> 
      <s:complexType name="ContactArray"> 
       <s:annotation> 
        <s:documentation> 
         Array of Contact 
        </s:documentation> 
       </s:annotation> 
       <s:complexContent> 
        <s:restriction base="soapenc:Array"> 
         <s:attribute ref="soapenc:arrayType" wsdl:arrayType="tns:Contact[]"> 
         </s:attribute> 
        </s:restriction> 
       </s:complexContent> 
      </s:complexType> 
      <s:complexType name="AddContactsResponse"> 
       <s:sequence> 
        <s:element minOccurs="1" maxOccurs="1" nillable="false" name="status" type="s:integer"> 
        </s:element> 
        <s:element minOccurs="1" maxOccurs="1" nillable="false" name="contactsCount" type="s:integer"> 
        </s:element> 
       </s:sequence> 
      </s:complexType> 
      <s:complexType name="Contact"> 
       <s:sequence> 
        <s:element minOccurs="1" maxOccurs="1" nillable="false" name="phone" type="s:string"> 
        </s:element> 
        <s:element minOccurs="1" maxOccurs="1" nillable="true" name="name" type="s:string"> 
        </s:element> 
        <s:element minOccurs="1" maxOccurs="1" nillable="true" name="firstName" type="s:string"> 
        </s:element> 
        <s:element minOccurs="1" maxOccurs="1" nillable="true" name="lastName" type="s:string"> 
        </s:element> 
        <s:element minOccurs="1" maxOccurs="1" nillable="true" name="customField1" type="s:string"> 
        </s:element> 
        <s:element minOccurs="1" maxOccurs="1" nillable="true" name="customField2" type="s:string"> 
        </s:element> 
        <s:element minOccurs="1" maxOccurs="1" nillable="true" name="customField3" type="s:string"> 
        </s:element> 
        <s:element minOccurs="1" maxOccurs="1" nillable="true" name="customField4" type="s:string"> 
        </s:element> 
        <s:element minOccurs="1" maxOccurs="1" nillable="true" name="customField5" type="s:string"> 
        </s:element> 
        <s:element minOccurs="1" maxOccurs="1" nillable="true" name="customField6" type="s:string"> 
        </s:element> 
       </s:sequence> 
      </s:complexType> 
     </s:schema> 
    </wsdl:types> 
    <wsdl:message name="addContactsSoapIn"> 
     <wsdl:part name="request" type="tns:AddContactsRequest"> 
     </wsdl:part> 
    </wsdl:message> 
    <wsdl:message name="addContactsSoapOut"> 
     <wsdl:part name="return" type="tns:AddContactsResponse"> 
     </wsdl:part> 
    </wsdl:message> 
    <wsdl:portType name="WebServiceSoap"> 
     <wsdl:operation name="addContacts"> 
      <wsdl:input message="tns:addContactsSoapIn"> 
      </wsdl:input> 
      <wsdl:output message="tns:addContactsSoapOut"> 
      </wsdl:output> 
     </wsdl:operation> 
    </wsdl:portType> 
    <wsdl:binding name="WebServiceSoap" type="tns:WebServiceSoap"> 
     <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"> 
     </soap:binding> 
     <wsdl:operation name="addContacts"> 
      <soap:operation soapAction="https://example.com/api/soap/addContacts"> 
      </soap:operation> 
      <wsdl:input> 
       <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="https://example.com/api/soap/" parts="request"> 
       </soap:body> 
      </wsdl:input> 
      <wsdl:output> 
       <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="https://example.com/api/soap/" parts="return"> 
       </soap:body> 
      </wsdl:output> 
     </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:service name="WebService"> 
     <wsdl:port name="WebServiceSoap" binding="tns:WebServiceSoap"> 
      <soap:address location="https://example.com/api/soap/soap.php"> 
      </soap:address> 
     </wsdl:port> 
    </wsdl:service> 
</wsdl:definitions> 

請求1(成功):

<?xml version="1.0" encoding="UTF-8"?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="https://example.com/api/soap/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 
    <SOAP-ENV:Body> 
     <ns1:addContacts> 
      <request xsi:type="ns1:AddContactsRequest"> 
       <contacts SOAP-ENC:arrayType="ns1:Contact[3]" xsi:type="ns1:ContactArray"> 
        <item xsi:type="ns1:Contact"> 
         <phone xsi:type="xsd:string">500555444</phone> 
         <name xsi:nil="true"/> 
         <firstName xsi:nil="true"/> 
         <lastName xsi:nil="true"/> 
         <customField1 xsi:nil="true"/> 
         <customField2 xsi:nil="true"/> 
         <customField3 xsi:nil="true"/> 
         <customField4 xsi:nil="true"/> 
         <customField5 xsi:nil="true"/> 
         <customField6 xsi:nil="true"/> 
        </item> 
        <item xsi:type="ns1:Contact"> 
         <phone xsi:type="xsd:string">500555777</phone> 
         <name xsi:type="xsd:string">Test 1</name> 
         <firstName xsi:nil="true"/> 
         <lastName xsi:nil="true"/> 
         <customField1 xsi:nil="true"/> 
         <customField2 xsi:nil="true"/> 
         <customField3 xsi:nil="true"/> 
         <customField4 xsi:nil="true"/> 
         <customField5 xsi:nil="true"/> 
         <customField6 xsi:nil="true"/> 
        </item> 
        <item xsi:type="ns1:Contact"> 
         <phone xsi:type="xsd:string">50</phone> 
         <name xsi:type="xsd:string">testName</name> 
         <firstName xsi:type="xsd:string">testFirstName</firstName> 
         <lastName xsi:type="xsd:string">testLastName</lastName> 
         <customField1 xsi:type="xsd:string">testCustomField1</customField1> 
         <customField2 xsi:type="xsd:string">testCustomField2</customField2> 
         <customField3 xsi:type="xsd:string">testCustomField3</customField3> 
         <customField4 xsi:type="xsd:string">testCustomField4</customField4> 
         <customField5 xsi:type="xsd:string">testCustomField5</customField5> 
         <customField6 xsi:type="xsd:string">testCustomField6</customField6> 
        </item> 
       </contacts> 
       <groups xsi:nil="true"/> 
       <createGroupsIfNotExist xsi:nil="true"/> 
      </request> 
     </ns1:addContacts> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

請求2(的SOAPFault錯誤請求)

<?xml version="1.0" encoding="UTF-8"?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="https://example.com/api/soap/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 
    <SOAP-ENV:Body> 
     <ns1:addContacts> 
      <request xsi:type="ns1:AddContactsRequest"> 
       <contacts SOAP-ENC:arrayType="ns1:Contact[4]" xsi:type="ns1:ContactArray"> 
        <item xsi:type="ns1:Contact"> 
         <phone xsi:type="xsd:string">500555444</phone> 
         <name xsi:nil="true"/> 
         <firstName xsi:nil="true"/> 
         <lastName xsi:nil="true"/> 
         <customField1 xsi:nil="true"/> 
         <customField2 xsi:nil="true"/> 
         <customField3 xsi:nil="true"/> 
         <customField4 xsi:nil="true"/> 
         <customField5 xsi:nil="true"/> 
         <customField6 xsi:nil="true"/> 
        </item> 
        <item xsi:type="ns1:Contact"> 
         <phone xsi:type="xsd:string">500555666</phone> 
         <name xsi:nil="true"/> 
         <firstName xsi:nil="true"/> 
         <lastName xsi:nil="true"/> 
         <customField1 xsi:nil="true"/> 
         <customField2 xsi:nil="true"/> 
         <customField3 xsi:nil="true"/> 
         <customField4 xsi:nil="true"/> 
         <customField5 xsi:nil="true"/> 
         <customField6 xsi:nil="true"/> 
        </item> 
        <item xsi:type="ns1:Contact"> 
         <phone xsi:type="xsd:string">500555777</phone> 
         <name xsi:type="xsd:string">Test 1</name> 
         <firstName xsi:nil="true"/> 
         <lastName xsi:nil="true"/> 
         <customField1 xsi:nil="true"/> 
         <customField2 xsi:nil="true"/> 
         <customField3 xsi:nil="true"/> 
         <customField4 xsi:nil="true"/> 
         <customField5 xsi:nil="true"/> 
         <customField6 xsi:nil="true"/> 
        </item> 
        <item xsi:type="ns1:Contact"> 
         <phone xsi:type="xsd:string">50</phone> 
         <name xsi:type="xsd:string">testName</name> 
         <firstName xsi:type="xsd:string">testFirstName</firstName> 
         <lastName xsi:type="xsd:string">testLastName</lastName> 
         <customField1 xsi:type="xsd:string">testCustomField1</customField1> 
         <customField2 xsi:type="xsd:string">testCustomField2</customField2> 
         <customField3 xsi:type="xsd:string">testCustomField3</customField3> 
         <customField4 xsi:type="xsd:string">testCustomField4</customField4> 
         <customField5 xsi:type="xsd:string">testCustomField5</customField5> 
         <customField6 xsi:type="xsd:string">testCustomField6</customField6> 
        </item> 
       </contacts> 
       <groups xsi:nil="true"/> 
       <createGroupsIfNotExist xsi:nil="true"/> 
      </request> 
     </ns1:addContacts> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

這些請求之間的唯一區別是在第二個請求一個更<item xsi:type="ns1:Contact">...</item>元件。

回答

1

我發現這是\SoapServer::handle方法在沒有參數($ soap_request)的情況下被調用的問題。它工作正常,如果我通過$HTTP_RAW_POST_DATA

global $HTTP_RAW_POST_DATA; 
$server->handle($HTTP_RAW_POST_DATA);