How to determine why cURL transfer is failing? - php

I've been using cURL to get the output of an external page and it's worked great for months, but suddenly it stopped working. My code is like this:
$ch = curl_init($URL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
The URL is valid, I checked that it still works and it does, and through debugging I found that the $output variable's value is false, which according to the PHP manual is what curl_exec() returns on failure.
So, after working for a long time, and without any changes to my code (that I know of), the cURL transfer is suddenly not working.
How can I debug why it's not working?

I would start with curl_error()

You can use the curl_error() function to see the error returned by curl.

Related

cURL no longer working

Edit: I have now checked by using an HTML form to submit the data via POST and this works perfectly so is definitely a cURL error any help hugely appreciated! Seems strange this worked last night and now not tonight...
o I managed to get my first cURL function working last night. For some reason (and with no changes that I'm aware of) it is not working today.
My code is:
<?php
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL,"http://www.example.com/api");
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, "apiKey=var1&message=var2&to=var3&from=var4");
curl_exec ($curl);
curl_close ($curl);
?>
Now I don't get any errors in the PHP log and I can't see any obvious syntax error. I've checked Im' using v7 and cURL is installed (if that's the correct technical term?). When I access the API address the POST data is going to without using this function it throws up an authentication error so at the very least I would expect this but only getting a blank page.
This leads me to believe the cURL itself is not POSTing the data but just ignoring it somehow. If I put headers in after the cURL they do follow this so their is definitely no fatal error in the code.
Sorry not to point the obvious out but have you checked for curl errors?
$err = curl_errno($curl);
$errmsg = curl_error($curl);
$info = curl_getinfo($curl);
So it turns out my provider that has the API stopped accepting requests to HTTP and now needs to be HTTPS.
A quick fix to this - though I hasten to add not optimal from a security standpoint which is fine for us as the data is NOT sensitive but something to bear in my mind - is to add this line of code:
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
At the beginning of your curl function.
I found the answer here which also discusses a much more robust fix:
http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/

php http_get function never returns

When I call http_get it never returns, my WEB page just stops outputting at that point. The destination URL never gets the request.
<?php //simplest test of http_get I could make
print "http://kayaker.net/php/image.php?id=ORCS084144<br>";
http_get ("http://kayaker.net/php/image.php?id=ORCS084144");
print "<br>back from http_get<br>";
?>
The original script was calling http_get in a loop to send data to several other processes on another server.
The loop stops on the first call to http_get. I tried calling flush(); after every line printed, no joy. I tried setting longer timeouts in the $options parameter to http_get, that didn't help. I tried calling http_request with HTTP_METH_GET in the first argument, same problem.
This kayaker URL is not the original, just a shorter example that still fails. I took one of the original URLs and pasted it into my browser address line, it worked fine. I pasted some of the original URLs into another scripting language (The llHTTPRequest function in LSL on Open Simulator) and they work fine from there.
I stored the program above at a location where you can run it from your browser and see it fail.
I pasted the URL to the program above into another scripting language and that at least returned an error status (500) and a message "Internal Server Error" which probably just means the test program didn't terminate properly.
I must be doing something very simple stupid and basically wrong.
But what is it?
Problem
You do not seem to have the right package installed (PECL pecl_http >= 0.1.0).
Fatal error: Call to undefined function http_get() in [snip] on line 8
Solution
You can either
install pecl_http as described in the documentation.
use a different function as mentioned in the comments (file_get_contents, curl)
Thanks to the comments above and the surprisingly helpful people at my WEB hosting company, I was able to write the following function:
function http_get($url)
{
$ch = curl_init(); // initialize curl handle
curl_setopt($ch, CURLOPT_URL,$url); // set url to post to
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);// allow redirects
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); // return into a variable
curl_setopt($ch, CURLOPT_TIMEOUT, 3); // times out after 4s
$result = curl_exec($ch); // run the whole process
curl_close($ch);
return($result);
} //http_get
This works for many different URLs, but does fail on some servers, I hope by playing with the options I can get it working there.

Limit time to execute a PHP line

I got a function to check if a URL is valid before putting it in my page, and I use
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$retcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
to do so. However, it recently happened that one external site wasn't working and was loading forever, reflecting that problem to my site as it got stuck at that last line of code, eventually ending in a timeout fatal error.How can I tell the server to only try curl_getinfo for a couple of seconds, and just return false if it's taking too long? It doesn't have to return an uncatchable timeout error that will compromise my page instead of just hiding an URL.
See http://php.net/manual/en/function.curl-setopt.php and use CURLOPT_CONNECTTIMEOUT.

PHP CURL GET request returns 500 where bash curl succeeds

I'm attempting to use PHP's CURL to make a GET request to a server and am having some difficulties doing so. When I make the request through PHP I am returned a 500 error from the external server. However, if I make the request using the bash curl, or visit the URL in a browser it succeeds.
I've stripped the PHP down to the bare essentials:
$url = 'http://example.com:8080/path/to/service?cmd=my_command&arg=example2.com';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_exec($ch);
print_r(curl_getinfo($ch));
curl_close($ch);
As stated this returns a 500 error from example.com. However, if I do the following:
[me#host ~] curl "http://example.com:8080/path/to/service?cmd=my_command&arg=example2.com"
I am returned the expected XML document.
What gives? It's got to be something with the encoding of the URL, as if I strip the $url var down to just http://example.com:8080 the PHP CURL request now responds with 200. I've tried replacing the & with %26 - that didn't work (nor would I expect it to, as & is valid in the URL there). I've tried doing what the answer for php curl sending vars using GET wierd results suggested, but that didn't help either.
What am I missing here? I'm sure that it's something absurdly simple, but it's escaping me.
Thanks!
EDIT: I've just attempted doing this in Python - just to see what happened - and it works fine there:
import urllib2
r = urllib2.urlopen(theURL)
r.read()
It turns out that the API I was accessing required a User-Agent for all requests, but did not provide any information to indicate such.
Is this a common thing? I can't find any other examples of anyone else doing this other than http://developer.github.com/v3/#user-agent-required
I was able to get things working just fine by adding
curl_setopt($ch, CURLOPT_USERAGENT, "User-Agent: Some-Agent/1.0");

What is wrong with this PHP cURL request to a Google API?

EDIT/UPDATE:
1) I tried the URL with just http (not https), and it worked in my browser. But, it did not work with PHP and cURL!
2) I read the curl error message, and it said Couldn't resolve host 'ajax.googleapis.com'. But, again, it could resolve the host from my web browser on the same machine!
3) Google explicitly stated that I needed the CURLOPT_REFERER to be set, so I'm keeping it.
Any other ideas? Thanks!
ORIGINAL POST:
When I enter this URL into my web browser, I get the JSON response I want. But, when I run the following cURL code in PHP5 (via Apache 2), the request fails. Can anyone point to some possible problems?
$url = "https://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=hola&langpair=es%7Cen&key=I-REMOVED-MY-API-KEY-FOR-STACKOVERFLOW-POST";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_REFERER, "http://my.ip.addr.ess/");
$response = curl_exec($ch);
var_dump($response);
The output is bool(false);
I have no idea what's wrong... do you? Thanks!
When the response if false, there was an error. Check for errors doing something like this:
if (($response = curl_exec($ch)) === FALSE) {
echo curl_error($ch);
exit();
}
In production code you definitely want to do something else on an error condition (instead of outputting the error message and exiting), but this will help you for debugging.
Probably because you're accessing a HTTPS resource.
Quick fix:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
Use http:// instead of https://. Code works fine without the key in the query string. CURLOPT_REFERER is also not necessary.

Categories