PHP Bad Request in Curl on SOAP interface of http:

2020-05-06 11:36发布

I am trying to call the url using curl in php. I get a BAD REQUEST error . if someone can help me,I do not get what the problem is

Their "recipe" is as follows: http://wl.filos.com.gr/services/WebService.asmx?op=PlaceSearch (look at soap 1.1)

The code I have is:

  <?      
        // xml data    
        $soap_request  = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
              $soap_request .= "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n";
              $soap_request .= " <soap:Body>\n";
              $soap_request .= "  <PlaceSearch xmlns=\"http://www.cyberlogic.gr/webservices/\">\n";
              $soap_request .= "  <xml><PlaceSearchRequest><Username>SERUNCD</Username><Password>TA78UNC</Password><PlaceType>Cities</PlaceType><Language>en</Language></PlaceSearchRequest></xml>\n";
              $soap_request .= "   </PlaceSearch>\n";
              $soap_request .= "  </soap:Body>\n";
              $soap_request .= "</soap:Envelope>";

          // heder    
               $header = array(
    "POST /services/WebService.asmx HTTP/1.1",
    "Host: wl.filos.com.gr",
    "Content-type: text/xml; charset=utf-8",
    "Content-length: ".strlen($soap_request),
    "SOAPAction: \"http://www.cyberlogic.gr/webservices/PlaceSearch\""
  );


        // call currl  
            $soap_do = curl_init();
                      curl_setopt($soap_do, CURLOPT_URL, "http://wl.filos.com.gr/services/WebService.asmx?op=PlaceSearch" );
                      curl_setopt($soap_do, CURLOPT_CONNECTTIMEOUT, 10);
                      curl_setopt($soap_do, CURLOPT_TIMEOUT,        10);
                      curl_setopt($soap_do, CURLOPT_RETURNTRANSFER, true );
                      curl_setopt($soap_do, CURLOPT_SSL_VERIFYPEER, false);
                      curl_setopt($soap_do, CURLOPT_SSL_VERIFYHOST, false);
                      curl_setopt($soap_do, CURLOPT_POST,           true );
                      curl_setopt($soap_do, CURLOPT_POSTFIELDS,     $soap_request);
                      curl_setopt($soap_do, CURLOPT_HTTPHEADER,     $header);
                      curl_getinfo($soap_do, CURLINFO_EFFECTIVE_URL);
                    curl_setopt($soap_do, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)');

                     $output = curl_exec($soap_do);
                         $info = curl_getinfo($soap_do);
                           print_r(curl_getinfo($soap_do)) ;
                      if(curl_exec($soap_do) === false) {
                        $err = 'Curl error: ' . curl_error($soap_do);
                        curl_close($soap_do);
                        print $err;
                      } else {
                        curl_close($soap_do);
                        print 'Operation completed without any errors  <br />';
                      }


                            echo "The server responded: <br />";
                            echo   " " .  $info['http_code'];
    ?>

5条回答
We Are One
2楼-- · 2020-05-06 12:11

As you don't have a WSDL for the SOAP interface of the www.cyberlogic.gr webservice, you won't benefit from using it compared with the other methods, e.g. the GET method:

<?php
/**
 *  Example for cyberlogic.gr GET webservice
 */

// create the request XML
$request            = new SimpleXMLElement("<PlaceSearchRequest/>");
$request->Username  = "SERUNCD";
$request->Password  = "TA78UNC";
$request->PlaceType = "Cities";
$request->Language  = "en";

$url    = "http://wl.filos.com.gr/services/WebService.asmx/PlaceSearch";
$result = simplexml_load_file($url . "?xml=" . urlencode($request->asXML()));
if ($result) {
    // process result
    $count = 0;
    foreach ($result->Response->Cities->City as $City) {
        printf("#%03d: %s (%s)\n", $count++, $City->CityName, $City["city_id"]);
    }
}

This example also shows how to access the city-id attribute which was something not easily possible with standard result parsing and mapping of PHP's SoapClient. As the result type remains undefined anyway, doing this in SoapClient isn't worth the steps it would need to take.

Example Output:

#000: Achladies (545)
#001: Afitos (338)
#002: Agia Paraskevi (548)
...
#142: Volos town (473)
#143: Vourvourou (420)
#144: Vrachos- Loutsa (922)
查看更多
我命由我不由天
3楼-- · 2020-05-06 12:15

The SOAP interface of the www.cyberlogic.gr webservice for the PlaceSearch requires you to pass the xml parameter properly encoded - otherwise you'll get a 400 Bad Request response.

This is normally done best by using the XML library of your choice, here I do that with SimpleXML which is pretty handy for your use-case:

// create the request XML
$request            = new SimpleXMLElement('<PlaceSearchRequest/>');
$request->Username  = 'SERUNCD';
$request->Password  = 'TA78UNC';
$request->PlaceType = 'Cities';
$request->Language  = 'en';

Next to creating correct XML for the parameter to be passed, the parameter itself needs to be properly encoded as well. As this involves some values configured, first of all define the data needed for the whole operation:

$soapUrl   = "http://wl.filos.com.gr/services/WebService.asmx";
$namespace = "http://www.cyberlogic.gr/webservices/";
$action    = "PlaceSearch";

and then use the $request object just created to turn it into the needed SOAP parameter. It is important here, that the XML encoding is applied correctly as well. Again, this should be done with the XML library of your choice, here I do that with DOMDocument:

// create the soap variable
$var = new DOMDocument();
$var->appendChild($var->createElementNS($namespace, 'xml'));
$var->documentElement->nodeValue = $request->asXML();
$soapVar = new SoapVar($var->saveXML($var->documentElement), XSD_ANYXML);

Note that the XML is properly assigned as XML to the nodeValue. This is important to create a valid request.

Now as $soapVar has been created, all it needs it so setup the SoapClient:

// create soap client in non-WSDL mode
$client = new SoapClient(null, array(
    'location' => $soapUrl,
    'uri'      => $namespace
));

And then do the request:

// place soap call
$result = $client->__soapCall(
    $action, array($soapVar), array('soapaction' => "$namespace$action")
);

And that's it already. Note that the API you have has some XML problems, namely it makes use of an XML element with the tag-name "xml" which is reserved and not allowed. That's also a sign that you should take extra care when you need to trouble-shoot your webservice requests. As curl can only give you a 400 Bar request, SoapClient does actually return much better error messages which help a lot to get things started.

What's left is the processing of the return value, here exemplary:

// process result
foreach ($result->PlaceSearch->Response->Cities->City as $i => $City) {
    printf("#%03d: %s\n", $i, $City->CityName);
}

Which outputs:

#000: Achladies
#001: Afitos
#002: Agia Paraskevi
...
#142: Volos town
#143: Vourvourou
#144: Vrachos- Loutsa

The code-example in full incl. error handling for the soap request:

/**
 * Example for cyberlogic.gr SOAP webservice
 */
$soapUrl   = "http://wl.filos.com.gr/services/WebService.asmx";
$namespace = "http://www.cyberlogic.gr/webservices/";
$action    = "PlaceSearch";

// create the request XML
$request            = new SimpleXMLElement('<PlaceSearchRequest/>');
$request->Username  = 'SERUNCD';
$request->Password  = 'TA78UNC';
$request->PlaceType = 'Cities';
$request->Language  = 'en';

// create the soap variable
$var = new DOMDocument();
$var->appendChild($var->createElementNS($namespace, 'xml'));
$var->documentElement->nodeValue = $request->asXML();
$soapVar = new SoapVar($var->saveXML($var->documentElement), XSD_ANYXML);

// create soap client in non-WSDL mode
$client = new SoapClient(null, array(
    'location' => $soapUrl,
    'uri'      => $namespace
));

try {
    // place soap call
    $result = $client->__soapCall(
        $action, array($soapVar), array('soapaction' => "$namespace$action")
    );

    // process result
    foreach ($result->PlaceSearch->Response->Cities->City as $i => $City) {
        printf("#%03d: %s\n", $i, $City->CityName);
    }
} catch (Exception $e) {
    echo $e->getMessage(), "\n";
    echo $client->__getLastRequest(); // set 'trace' => true SoapClient option
}
查看更多
4楼-- · 2020-05-06 12:16

As I understand, you need to use PHP SOAP for SOAP request OR PHP cURL for HTTP POST or GET request.

Here is your code:

$soap_request  = 'xml='.urlencode(trim('
<PlaceSearchRequest>
    <Username>SERUNCD</Username>
    <Password>TA78UNC</Password>
    <PlaceType>Cities</PlaceType>
    <Language>en</Language>
</PlaceSearchRequest>
'));

$header = array(
    'POST /services/WebService.asmx HTTP/1.1',
    'Host: wl.filos.com.gr',
    'Content-Type: application/x-www-form-urlencoded',
    'Content-Length: '.strlen($soap_request),
);

$soap_do = curl_init();
curl_setopt($soap_do, CURLOPT_URL, 'http://wl.filos.com.gr/services/WebService.asmx?op=PlaceSearch');
curl_setopt($soap_do, CURLOPT_HEADER, false);
curl_setopt($soap_do, CURLOPT_CONNECTTIMEOUT, 100);
curl_setopt($soap_do, CURLOPT_TIMEOUT,        100);
curl_setopt($soap_do, CURLOPT_RETURNTRANSFER, true);
curl_setopt($soap_do, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($soap_do, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($soap_do, CURLOPT_HTTPHEADER,     $header);
curl_setopt($soap_do, CURLOPT_POST,           true);
curl_setopt($soap_do, CURLOPT_POSTFIELDS,     $soap_request);
curl_setopt($soap_do, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)');


$output = curl_exec($soap_do);
$info = curl_getinfo($soap_do);

if (curl_exec($soap_do) === FALSE)
{
    $err = 'Curl error: ' . curl_error($soap_do);
    curl_close($soap_do);
    print $err;
}
else
{
    curl_close($soap_do);
}

echo 'The server responded: '.$info['http_code']."\n";
echo 'Output: '.$output;
echo "\n";

Run it in terminal with php your_code.php for example.

Here is output for current XML string data: <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><soap:Fault><soap:Code><soap:Value>soap:Receiver</soap:Value></soap:Code><soap:Reason><soap:Text xml:lang="en">Server was unable to process request. ---&gt; Data at the root level is invalid. Line 1, position 1.</soap:Text></soap:Reason><soap:Detail /></soap:Fault></soap:Body></soap:Envelope>

查看更多
劳资没心,怎么记你
5楼-- · 2020-05-06 12:17

Done!

$soap_request  = 'xml='.urlencode(trim('
<?xml version="1.0" encoding="utf-8"?>
<PlaceSearchRequest>
    <Username>SERUNCD</Username>
    <Password>TA78UNC</Password>
    <PlaceType>Cities</PlaceType>
    <Language>en</Language>
</PlaceSearchRequest>
'));

$header = array(
    'POST /services/WebService.asmx HTTP/1.1',
    'Host: wl.filos.com.gr',
    'Content-Type: application/x-www-form-urlencoded',
    'Content-Length: '.strlen($soap_request),
);

$soap_do = curl_init();
curl_setopt($soap_do, CURLOPT_URL, 'http://wl.filos.com.gr/services/WebService.asmx/PlaceSearch');
curl_setopt($soap_do, CURLOPT_HEADER, false);
curl_setopt($soap_do, CURLOPT_CONNECTTIMEOUT, 100);
curl_setopt($soap_do, CURLOPT_TIMEOUT,        100);
curl_setopt($soap_do, CURLOPT_RETURNTRANSFER, true);
curl_setopt($soap_do, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($soap_do, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($soap_do, CURLOPT_HTTPHEADER,     $header);
curl_setopt($soap_do, CURLOPT_POST,           true);
curl_setopt($soap_do, CURLOPT_POSTFIELDS,     $soap_request);
curl_setopt($soap_do, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)');


$output = curl_exec($soap_do);
$info = curl_getinfo($soap_do);

if (curl_exec($soap_do) === FALSE)
{
    $err = 'Curl error: ' . curl_error($soap_do);
    curl_close($soap_do);
    print $err;
}
else
{
    curl_close($soap_do);
}

echo 'The server responded: '.$info['http_code']."\n";
echo 'Output: '.$output;
echo "\n";
查看更多
相关推荐>>
6楼-- · 2020-05-06 12:29

You can try "Content-type: application/xml; charset=utf-8" in your header line?

查看更多
登录 后发表回答