Forum Moderators: coopster

Message Too Old, No Replies

cURL and XML API issue

         

Piggo

11:16 am on Aug 15, 2011 (gmt 0)

10+ Year Member



My URL+xml request works when I put it in the browser address bar. But when I try and make the same request with cURL then the XML API returns an Error, which makes me think that the parameters in the request has been messed up somehow or I'm not pasing it quite right.

I've tried hte same cURL code with a simpler API that doesn't require authentication and it works fine so I wonder if the Credentials section is causing my error?

This is the code I am using:

<?php
$url = "http://www.example.com/example/example.do?xml=";

$user = "eg";
$pw = "egpw";
$remoteip = "00.100.00.000";
$country = "UK";
$city = "Manchester";
$n = "\n\n";

$xml_data = '<?xml version=\'1.0\' encoding=\'UTF-8\'?'.'>'.$n.'<TempList><Credentials username='.$user.' password='.$pw.' remoteIp='.$remoteip.'/><Country>'.$country.'</Country><City>'.$city.'</City></TempList>';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_data);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
echo $output;
?>

THANK YOU

astupidname

11:59 am on Aug 15, 2011 (gmt 0)

10+ Year Member



xml attributes should be quoted and your $user and $pw as well as $remoteip are not being quoted in the $xml_data, so maybe the xml's not being read on the other end? (by the api)
Welcome to webmasterworld!

Piggo

12:16 pm on Aug 15, 2011 (gmt 0)

10+ Year Member



Hi, Thanks for your quick repsonse. What exactly do you mean?

penders

1:34 pm on Aug 15, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Just following on from what astupidname was saying... you have quoted the version and encoding attributes in the XML declaration (ie. put quotes around the attribute values) but not around your other attributes. It's probably easier using HEREDOC syntax...

$xml_data = <<<ENDOFXML 
<?xml version="1.0" encoding="UTF-8"?>
<TempList><Credentials username="$user" password="$pw" remoteIp="$remoteip"/><Country>$country</Country><City>$city</City></TempList>
ENDOFXML;


You also had 2xLFs after the XML declaration - although this shouldn't matter?

$url = "http://www.example.com/example/example.do?xml=";


You should probably remove the '?xml=' part in the URL, since you are now POSTing the data and having a URL param might confuse your script (ie. perhaps the URL param takes priority?).

Piggo

3:14 pm on Aug 15, 2011 (gmt 0)

10+ Year Member



Thanks for that. I've updated the URL as suggested:

$url = "http://www.example.com/example/example.do";

Do you mean to remove the quote marks around the Credentials data? I've tried this but for some reason the page won't load. When I've worked through this it seems to be the HEREDOC syntax that's causing the problem. As when I take the HEREDOC section out the page does at least load.

penders

4:29 pm on Aug 15, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Do you mean to remove the quote marks around the Credentials data?


You need to insert quote marks around the attribute values. You don't have any in your original code.

In your original code, you have:
$xml_data = '....username='.$user.' pass....';

Which results in the following being assigned to your $xml_data variable:
....username=eg pass....

It should be:
....username="eg" pass....


ie. The attribute values must be quoted.

The HEREDOC syntax should work OK. However, there appears to be an extra space at the end of the first line in my post above which must be removed, otherwise you will get a "Parse error: syntax error, unexpected T_SL in...."
$xml_data = <<<ENDOFXML#


Check for a space where the # is and remove it.

Piggo

7:13 pm on Aug 15, 2011 (gmt 0)

10+ Year Member



Hi, Thanks again for your help. I've now inserted quote marks around my attribute values and checked for spaces after the <<<ENDOFXML and have:

$url = "http://www.example.com/example/example.do";
$user = "eg";
$pw = "egpw";
$remoteip = "00.100.00.000";
$country = "UK";
$city = "Manchester";

$xml_data = <<<ENDOFXML
<?xml version="1.0" encoding="UTF-8"?><TempList><Credentials username="$user" password="$pw" remoteIp="$remoteip"/><Country>$country</Country><City>$city</City></TempList>
ENDOFXML;

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_data);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
echo $ch;

However, this still loads a white page in FF and an Error 500 on IE. When I view the source in IE is says
<title>HTTP 500 Internal Server Error</title>
.....
<!-- This row is for HTTP status code, as well as the divider-->
<td id="http500Align" class="errorCodeAndDivider" align="right"><ID id="http500">&nbsp;HTTP 500</ID>

Is this something else I am doing wrong?

Piggo

9:33 pm on Aug 15, 2011 (gmt 0)

10+ Year Member



UPDATE - My page loads and doesn't white screen in FF or error in IE now (for some reason) but I still get an error response from the API (when I view the source it has <Error id="9999"><Message></Message></Error>...) for requests that work correctly when I put them in the address bar. Is there something obvious I am missing here does anybody know. This is my code now:

(The full URL is http://www.example.com/example/example.do?xml=)

$url = "http://www.example.com/example/example.do";
$user = "eg";
$pw = "egpw";
$remoteip = "00.100.00.000";
$country = "UK";
$city = "Manchester";

$xmldata = <<<ENDOFXML
<?xml version="1.0" encoding="UTF-8"?>
<TempList>
<Credentials username="$user" password="$pw" remoteIp="$remoteip"/>
<Country>$country</Country>
<City>$city</City>
</TempList>
ENDOFXML;

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_data);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
echo $ch;

THANKS

astupidname

7:08 am on Aug 16, 2011 (gmt 0)

10+ Year Member



What exactly do you mean?


Sorry I was a bit brief with my post there, thanks to penders for following it up more appropriately.

My URL+xml request works when I put it in the browser address bar. But when I try and make the same request with cURL then the XML API returns an Error

.....
but I still get an error response from the API ..... for requests that work correctly when I put them in the address bar. Is there something obvious I am missing here does anybody know.


O.K. the next obvious question to ask you, are you certain the API supports POST requests? When you access through the address bar that is in fact a GET request and works for you. It would seem wrong to me for the API to take a username and password and not support POST requests, but well the web is full of idiocies like that, so who knows. Up to you to find out for sure if the API supports POST or not, if you have not already and are not certain it does.
How nice their error code of 9999 does not give you any message.

Oh boy, wait a second here the light bulb just went off! Just realized that the $xmldata that you are passing is not a name->value pair but just a straight value only with no name! So I'm betting the API is looking for a post or get variable by the name of 'xml' and not finding one.
So, change this:
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_data);

To the following:
curl_setopt($ch, CURLOPT_POSTFIELDS, 'xml='.$xml_data);


Here's hoping that's it, good luck!

astupidname

7:21 am on Aug 16, 2011 (gmt 0)

10+ Year Member



Actually, may have missed one other thing, take that one step further yet, POST or GET request variable values should be escaped, so do this:
curl_setopt($ch, CURLOPT_POSTFIELDS, 'xml='.urlencode($xml_data));

Piggo

7:59 am on Aug 16, 2011 (gmt 0)

10+ Year Member



Thanks so much for all of that. The API claims to take POST and GET requests, so that's checked. I added in the the extras you suggested to the $xmldata but I still have the same problem.

If there's nothing else wrong with my code, I've now come to the conclusion it might be some unknown problem with the API, so will look into that now.

Thanks, will keep you posted!

astupidname

10:08 am on Aug 16, 2011 (gmt 0)

10+ Year Member



Oh wow, I really really really thought those last two "discoveries" by me would have done it, so hmmm will look a bit more here. Otherwise, good luck!
Wait, another light bulb flashing here (dim though it may be...), wondering if there's problems with the headers being sent maybe?
Try one more thing here, try changing this:
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));

to this:
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded'));


If it still does not work, I'd have to ask does the API not have sufficient example documentation to look at and see how to use it? If you'd like to send me a sticky message through your control panel here with a link to the API documentation, or just post it here, I'd have a look at that.

Piggo

10:18 am on Aug 16, 2011 (gmt 0)

10+ Year Member



Wow, thank you so much. Have just changed the header thing as you suggested and it works. It connects to the API and shows the results correctly in the browser. Now I can get on with the rest of it! I was beginning to think it would never work. Brilliant, thanks for your time.

astupidname

10:29 am on Aug 16, 2011 (gmt 0)

10+ Year Member



Great! Congratulations on getting your life back now, eh? Happy trails!