I'm having some weirdness with returning cURL response code errors. The following code, despite the remote host throwing a 404, does not cURL error. Why?
$ch = curl_init('http://www.google.com/13ewsdasd'); //<-- definitely a 404
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
echo curl_exec($ch) ? 'All OK' : 'Error: '.curl_error($ch); //'All OK'
I found this answer that suggested using curl_get_Info with the CURL_INFO_HTTP_CODE flag, but no joy there, either - that just gives me "0".
$ch = curl_init('http://www.google.com/13ewsdasd'); //<-- still a 404
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE); //<-- 0
I seem to recall issues detecting errors with cURL before. Am I missing something obvious? I just want to detect when the remote server throws a 404 or 500.
Another answer suggested doing this via get_headers(), but it seems silly to have to fire a second, separate request just to find out the response code of the first one.
Related
So I have obviously googled the error - but PHP (PHP 7.4.4 (cli)) curl gives me the error:
Curl error: operation aborted by callback with the following code:
private function curl_post($url,$post,$file = null,$file_type = 'audio/wav'){
$ch = curl_init($url);
if (!empty($file)){
$post['SoundFile'] = new CURLFile(UPLOAD_PATH.$file,$file_type,$file);
}
// Assign POST data
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$post);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
if(curl_errno($ch)) echo 'Curl error: '.curl_error($ch);
curl_close($ch);
print'<pre>Curl (rec): '."\n";print_r($result);print'</pre>';
}
I control both (Ubuntu) servers and have rebooted them both. I am posting a fairly large amount of data but in the Google searching this didn't seem to be what is triggering the curl_error. Does anyone know what is causing it? It was working perfectly fine and then it stopped.
Additionally putting file_put_contents(time().'.txt','log'); as a break in my receiving server does log the response. So its clearly landing in the right area.
Additionally what I will say is that the 2 servers talk a number of times to each other through curl (so one curls to one then back a bit). Furthermore - error 42 is the CURL response but https://curl.haxx.se/libcurl/c/libcurl-errors.html doesn't seem to provide much help. I've tried tracing the various calls to each other and can't see why it is breaking - it errors/breaks before the post/calls even occur.
So I found the answer and I hope this helps anyone else in this situation. The reason being was because the file was missing on the server for the CURLFile (having previously been there). My code now reads:
if (!empty($file) && is_file(UPLOAD_PATH.$file)){
$post['SoundFile'] = new CURLFile(UPLOAD_PATH.$file,$file_type,$file);
}
And this no longer generates the error. The key was that it errored even before submitting the post but the error itself wasn't that helpful until I broke it down in a separate test script and added the file element back in.
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/
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.
I am running the following command and getting an exception:
$headers = get_headers("http://www.moneysupermarket.com/mortgages/", 1);
How do I handle this exception (in my case, ignore this url as it is causing an exception).
I have tried:
try/catch
The code in this link: https://stackoverflow.com/a/6184127/1486303
However, I still get this error appear (which I want ignored).
Thanks!
NEW VERSION
Again this's not the right answer of the question, but avoiding the error, can give the expected result.
get_headers do an HTTP GET without Agent, so moneysupermarket.com don't like it, so use ini_set to set the default user agent in request, and all work well:
ini_set("user_agent","Mozilla custom agent");
$headers = get_headers("http://www.moneysupermarket.com/mortgages/", 1);
PREVIOUS
Apparently moneysupermarket.com reset a connection if request is not well formatted, do the request using cUrl (take from curl man page):
// create a new cURL resource
$ch = curl_init();
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, "http://www.moneysupermarket.com/mortgages/");
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla custom agent");
// grab URL and pass it to the browser
curl_exec($ch);
// close cURL resource, and free up system resources
curl_close($ch);
There's no exception. get_headers() returns FALSE on error. There's a warning message though, but that is no exception, thus cannot get catched. For warnings and other errors see: http://www.php.net/manual/en/function.set-error-handler.php
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.