Handling Soap timeouts in PHP

前端 未结 8 1781
囚心锁ツ
囚心锁ツ 2021-01-30 09:05

I\'m working on a project where I am verifying information from a user with a SOAP web service. I currently am taking care of errors assuming that I\'m receiving responses from

8条回答
  •  深忆病人
    2021-01-30 09:53

    1) In case of timeout, PHP throws a SoapFault exception with faultcode="HTTP" and faultstring="Error Fetching http headers".

    2) In my opinion, the best way to distinguish between a timeout error and web service issues is by looking at the faultcode and faultstring members of the SoapFault class.
    In particular, the faultcode element is intended for use by software to provide an algorithmic mechanism for identifying the fault.
    As you can also read in a comment of the PHP manual, there is no method to read the faultcode property, so you have to access it directly (eg. $e->faultcode), because the getCode() method does not work.
    The SOAP 1.1 Spec defines four possible values for the faultcode field:

    • VersionMismatch: The processing party found an invalid namespace for the SOAP Envelope element
    • MustUnderstand: An immediate child element of the SOAP Header element that was either not understood or not obeyed by the processing party contained a SOAP mustUnderstand attribute with a value of "1"
    • Client: The Client class of errors indicate that the message was incorrectly formed or did not contain the appropriate information in order to succeed. For example, the message could lack the proper authentication or payment information. It is generally an indication that the message should not be resent without change.
    • Server: The Server class of errors indicate that the message could not be processed for reasons not directly attributable to the contents of the message itself but rather to the processing of the message. For example, processing could include communicating with an upstream processor, which didn't respond. The message may succeed at a later point in time.

    In addition to those codes, PHP uses the HTTP code for identifying the errors happening at the protocol level (eg.: socket errors); for example, if you search for add_soap_fault in the ext/soap/php_http.c source code you can see when some of these kind of faults are generated.
    By searching for the add_soap_fault and soap_server_fault functions in the PHP SOAP extension source files, I've built the following list of PHP SoapFault exceptions:

    HTTP
    ----
    Unable to parse URL
    Unknown protocol. Only http and https are allowed.
    SSL support is not available in this build
    Could not connect to host
    Failed Sending HTTP SOAP request
    Failed to create stream??
    Error Fetching http headers
    Error Fetching http body: No Content-Length: connection closed or chunked data
    Redirection limit reached: aborting
    Didn't recieve an xml document
    Unknown Content-Encoding
    Can't uncompress compressed response
    Error build soap request
    
    
    VersionMismatch
    ---------------
    Wrong Version
    
    
    Client
    ------
    A SOAP 1.2 envelope can contain only Header and Body
    A SOAP Body element cannot have non Namespace qualified attributes
    A SOAP Envelope element cannot have non Namespace qualified attributes
    A SOAP Header element cannot have non Namespace qualified attributes
    Bad Request
    Body must be present in a SOAP envelope
    Can't find response data
    DTD are not supported by SOAP
    encodingStyle cannot be specified on the Body
    encodingStyle cannot be specified on the Envelope
    encodingStyle cannot be specified on the Header
    Error cannot find parameter
    Error could not find "location" property
    Error finding "uri" property
    looks like we got "Body" with several functions call
    looks like we got "Body" without function call
    looks like we got no XML document
    looks like we got XML without "Envelope" element
    Missing parameter
    mustUnderstand value is not boolean
    SoapClient::__doRequest() failed
    SoapClient::__doRequest() returned non string value
    Unknown Data Encoding Style
    Unknown Error
    DataEncodingUnknown
    
    
    MustUnderstand
    --------------
    Header not understood
    
    
    Server
    ------
    Couldn't find WSDL
    DTD are not supported by SOAP
    Unknown SOAP version
    WSDL generation is not supported yet
    

    3) To simulate the timeout condition, try with the following code:

    soapclient.php

     "http://localhost/soapserver.php",
        'uri'      => "http://localhost/soapserver.php",
        'trace'    => 1
      )
    );
    
    try {
        echo $return = $client->__soapCall("add",array(41, 51));
    } catch (SoapFault $e) {
        echo "
    SoapFault: ".print_r($e, true)."
    \n"; //echo "
    faultcode: '".$e->faultcode."'
    "; //echo "
    faultstring: '".$e->getMessage()."'
    "; } ?>

    soapserver.php

     'http://localhost/soapserver.php'));
    $soap->addFunction("add");
    $soap->handle();
    
    ?>
    

    Notice the sleep call in the SoapServer.php script with a time (20) longest than the time (10) specified for the default_socket_timeout parameter in the SoapClient.php script.
    If you want to simulate a service unavailability, you could for example change the location protocol from http to https in the soapclient.php script, assuming that your web server is not configured for SSL; by doing this, PHP should throw a "Could not connect to host" SoapFault.

提交回复
热议问题