HTTP Error: socket read of headers timed out

Help
2009-05-14
2013-06-06
  • Ilija Stevcev
    Ilija Stevcev
    2009-05-14

    Hey guys,

    I was hoping you could help me with a problem I haven't been able to fix. I am trying to use nusoap to make a call to a WCF service. I keep getting the "HTTP Error: socket read of headers timed out" error though.

    Here's the code:

    <?php

    require_once('nusoap/nusoap.php');

    set_time_limit(600);

    $accountID = '<removed>';
    $password = '<removed>';

    $deliveryclient = new nusoap_client('http://api7.publicaster.com/Pub7API/Delivery.svc?wsdl', true);
    $deliveryclient->soap_defencoding = 'utf-8';

    print_r($deliveryclient);

    $err = $deliveryclient->getError();
    if ($err)
    {
        echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';
    }

    $authparam = array('AccountID' => $accountID, 'Password' => $password);
    $deliveryclient->call('Authenticate', array('parameters' => $authparam), 'http://BlueSkyFactory.Publicaster7.Public.API', 'http://BlueSkyFactory.Publicaster7.Public.API/IDelivery/Authenticate', false, false, 'document', 'literal');

    $recipients_data = "email\tfirstname\tlastname\nilijas@blueskyfactory.com\tilija\tstevcev";
    $sendData = array('RecipientsData' => $recipients_data, 'Recipients' => null, 'ContentID' => 1, 'FromID' => 1, 'Subject' => 'Testing API PHP', 'XHeaders' => null);
    $param = array('SendData' => $sendData);
    $result = $deliveryclient->call('QuickSend', array('parameters' => $param), 'http://BlueSkyFactory.Publicaster7.Public.API', 'http://BlueSkyFactory.Publicaster7.Public.API/IDelivery/QuickSend', false, false, 'document', 'literal');

    if ($deliveryclient->fault)
    {
        echo '<h2>Fault</h2><pre>';
        print_r($result);
        echo '</pre>';
    }
    else
    {
        // Check for errors
        $err = $deliveryclient->getError();
        if ($err)
        {
            // Display the error
            echo '<h2>Error</h2><pre>' . $err . '</pre>';
        }
        else
        {
            // Display the result
            echo '<h2>Result</h2><pre>';
            print_r($result);
            echo '</pre>';
        }
    }

    echo '<h2>Request</h2><pre>' . htmlspecialchars($deliveryclient->request, ENT_QUOTES) . '</pre>';
    echo '<h2>Response</h2><pre>' . htmlspecialchars($deliveryclient->response, ENT_QUOTES) . '</pre>';
    echo '<h2>Debug</h2><pre>' . htmlspecialchars($deliveryclient->debug_str, ENT_QUOTES) . '</pre>';

    unset($deliveryclient);

    ?>

    Thanks

     
    • Ilija Stevcev
      Ilija Stevcev
      2009-05-29

      Any takers?

       
    • seaan
      seaan
      2009-06-04

      Hi,
      Could you already ascertain whether the time out happens at the call to Authenticate or QuickSend, to start with?
      Regards
      Sergio

       
      • Ilija Stevcev
        Ilija Stevcev
        2009-06-04

        Hi Sergio,

        It looks like it's only happening on the QuickSend method call. I suspect it has to do with how the data is serialized.

        Thanks,
        Ilija

         
        • seaan
          seaan
          2009-06-04

          Could you post the specs of how QuickSend operation expects the request to be structured?
          I usually use "soapval" to build operation's parameters and I serialize them before calling the method.
          If you could post the structure request to feed to QuickSend I may try to suggest you an alternative approach.
          Bye
          Sergio

           
          • Ilija Stevcev
            Ilija Stevcev
            2009-06-04

            Hi,

            It's a .NET WCF service, here's the method prototype:

            bool QuickSend(QuickSendData SendData);

            And the QuickSendData class:

            [DataContract(Namespace = "http://BlueSkyFactory.Publicaster7.Public.API"), Serializable]
            public class QuickSendData
            {
                [DataMember]
                public DataSet Recipients { get; set; }

                [DataMember]
                public string RecipientsData { get; set; }

                [DataMember]
                public int ContentID { get; set; }

                [DataMember]
                public int FromID { get; set; }

                [DataMember]
                public string Subject { get; set; }

                [DataMember]
                public ArrayOfKeyValueOfanyTypeanyTypeKeyValueOfanyTypeanyType[] XHeaders { get; set; }
            }

            Here's the WSDL:

            http://api7.publicaster.com/Pub7API/Delivery.svc?wsdl

            The Recipients data member is optional, if it's null when you call the method, then it uses the RecipientsData member instead for it's calculation. The reason for this is that PHP(or pretty much anything else) does not play well with the .NET DataSet class.

            Thanks,
            Ilija

             
    • seaan
      seaan
      2009-06-04

      Ok,
      I can't tell what's wrong in your code, but this is how I usually build params and consume method, applied to your case:

      $recipients_data = "email\tfirstname\tlastname\nilijas@blueskyfactory.com\tilija\tstevcev";
      $sendData = new soapval ('SendData',
      'QuickSendData',
      array('RecipientsData' => $recipients_data, 'Recipients' => null, 'ContentID' => 1, 'FromID' => 1, 'Subject' => 'Testing API PHP', 'XHeaders' => null),
      '<namespace for this type if any otherwise false'>,
      false,
      false);
      $xml_request = $sendData->serialize('literal');
      $result = $deliveryclient->call('QuickSend',$xml_request);

      I was hinting to the same approach also in this post:
      https://sourceforge.net/forum/message.php?msg_id=7411000

      Hope this helps
      Regards
      Sergio

       
      • Ilija Stevcev
        Ilija Stevcev
        2009-06-05

        Thanks for this code, but it looks like it's still not forming the request correctly.

        I ran a packet sniffer, and here's what a working request(from a .NET client I wrote) looks like:

        <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
        <s:Body>
        <QuickSend xmlns="http://BlueSkyFactory.Publicaster7.Public.API">
        <SendData xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <ContentID>1</ContentID>
        <FromID>1</FromID>
        <Recipients i:nil="true"/>
        <RecipientsData>email
        ilijas@blueskyfactory.com</RecipientsData>
        <Subject>Testing Method</Subject>
        <XHeaders i:nil="true" xmlns:a="http://schemas.datacontract.org/2004/07/"/>
        </SendData>
        </QuickSend>
        </s:Body>
        </s:Envelope>

        Here's what nusoap is generating:

        <?xml version="1.0" encoding="utf-8"?>
        <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns7099="http://tempuri.org">
        <SOAP-ENV:Body>
        <SendData>
        <RecipientsData>email    firstname    lastname
        ilijas@blueskyfactory.com    ilija    stevcev</RecipientsData>
        <Recipients/>
        <ContentID>1</ContentID>
        <FromID>1</FromID>
        <Subject>Testing API PHP</Subject>
        <XHeaders/>
        </SendData>
        </SOAP-ENV:Body>
        </SOAP-ENV:Envelope>

        With this code:

        $recipients_data = "email\tfirstname\tlastname\nilijas@blueskyfactory.com\tilija\tstevcev";
        $sendData = new soapval ('SendData',
        'QuickSendData',
        array('RecipientsData' => $recipients_data, 'Recipients' => null, 'ContentID' => 1, 'FromID' => 1, 'Subject' => 'Testing API PHP', 'XHeaders' => null),
        false,
        false);
        $xml_request = $sendData->serialize('literal');
        $result = $deliveryclient->call('QuickSend', $xml_request);

        I'm not sure why it's not wrapping it all in a <QuickSend>, or putting i:nil="true" as an attribute on the null parameters.

        Thanks,
        Ilija

         
    • seaan
      seaan
      2009-06-06

      Ok,
      now that you posted a sample packet I can probably attempt a better try, also because I see Recipients and XHeaders have "nil" attribute (the i: is the namespace alias which you can specify in the soapval call) and I did not notice the wrapping QuickSend.

      $recipients_data = "email\tfirstname\tlastname\nilijas@blueskyfactory.com\tilija\tstevcev";
      // I'm not sure if the namespace is referring to the item type (4th arg) or value (5th arg):
      // I'll go for type, try with value if this does not work (see soapval docs)
      $recipients = new soapval ('Recipients','','','http://www.w3.org/2001/XMLSchema-instance',false,array('nil'=>'true'));
      $xheaders = new soapval ('Recipients','','','http://www.w3.org/2001/XMLSchema-instance',false,array('nil'=>'true'));

      $sendData = new soapval ('SendData', 
      '',  array('RecipientsData' => $recipients_data, 'Recipients' => null, 'ContentID' => 1, 'FromID' => 1, 'Subject' => 'Testing API PHP', 'XHeaders' => null), 
      'http://www.w3.org/2001/XMLSchema-instance', false,false);

      //finally enclosing item
      $quicksend = new soapval ('QuickSend','',$sendData, 
      'http://BlueSkyFactory.Publicaster7.Public.API', false,false);

      $xml_request = $quicksend->serialize('literal'); 
      $result = $deliveryclient->call('QuickSend', $xml_request);

       
      • Ilija Stevcev
        Ilija Stevcev
        2009-06-08

        Hi pigreco314,

        I appreciate all of your help, but it looks like it's still not serializing properly. Here's what the new code generates:

        <?xml version="1.0" encoding="utf-8"?>
        <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2015="http://tempuri.org">
        <SOAP-ENV:Body>
        <nu9290:QuickSend xmlns:nu9290="http://BlueSkyFactory.Publicaster7.Public.API"><nu7920:SendData xmlns:nu7920="http://www.w3.org/2001/XMLSchema-instance">
        <RecipientsData>email    firstname    lastname
        ilijas@blueskyfactory.com    ilija    stevcev</RecipientsData>
        <nu3043:Recipients xmlns:nu3043="http://www.w3.org/2001/XMLSchema-instance" nil="true"></nu3043:Recipients>
        <ContentID>1</ContentID>
        <FromID>1</FromID>
        <Subject>Testing API PHP</Subject>
        <nu3363:XHeaders xmlns:nu3363="http://www.w3.org/2001/XMLSchema-instance" nil="true"></nu3363:XHeaders>
        </nu7920:SendData>
        </nu9290:QuickSend>
        </SOAP-ENV:Body>
        </SOAP-ENV:Envelope>

        So instead of nu3363:nil="true", it's just nil="true". I don't know if that affects it or not, but my calls using this method still don't work.

        Thanks,
        Ilija