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.
Related
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/
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.
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'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.
I have the same code running on multiple sites/servers. 2 days ago the code started returning http_code = 0 and the error message "empty reply from server" on one of the servers.
Can anyone shed any light as to why a particular server would be working one day, then not working the next? I have submitted a ticket to the ISP explaining the issue but they cannot seem to find what is wrong (yet).
I guess the question really is, what would/could change on a server to stop this from working?
What is interesting tho is the url I am referencing doesnt get touched on the server returning the error. If I change the url to point to something that doesnt exist, the same error is returned. So it appears that CURL POST references in total are being rejected by the server. I currently have other CURL scripts that are hitting these problem sites that are still working, but they do not have POST options in them.
The issue is definitely related to CURL POST requests on this server, and they are being rejected pretty much immediately.
On the server in question I have 15+ separate accounts and every one of them returns the same result so I dont think its anything I have changed as I know I havent made any wholesale changes to ALL the sites at the time when this issue arose. Of the 6 other sites I have hosted elsewhere, everything is still working fine with exactly the same code.
I have tried various combinations/changes to options from posts I have read but nothing has really made a difference, the working sites still work and the non-working sites still dont.
function sendWSRequest($url, $xml) {
// $headers[] = 'Content-Type: application/xml; charset=utf-8';
$headers[] = 'Content-Type: text/xml; charset=utf-8';
$headers[] = 'Content-Length: ' . strlen($xml);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, true);
// curl_setopt($ch, CURLINFO_HEADER_OUT, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
// curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
$result = curl_exec($ch);
if($result===false) {
print 'error with curl - '.curl_error($ch).'<br />';
}
$info = curl_getinfo($ch);
curl_close($ch);
return $result;
}
Any help would be greatly appreciated.
EDIT
To summarise based on further investigations, when the script errors, nothing registers in the server access logs. So it appears that CURL requests containing POST options are being rejected before access is granted/logged...
Cheers
Greg J
I know this is an old thread, but I found a solution that may save someone else a headache:
I just began encountering this exact problem with a web site hosted at GoDaddy which was working until recently. To investigate the problem I created an HTML page with a form containing the same fields being submitted in the POST data via cURL.
The browser-submitted HTML form worked while the cURL POST resulted in the Empty reply from server error. So I examined the difference between the headers submitted by the browser and those submitted by cURL using the PHP apache_request_headers() function on my development system where both the cURL and browser submissions worked.
As soon as I added the "User-Agent" header submitted by my browser to the cURL POST, the problem site worked as expected instead of returning an empty reply:
CURLOPT_HTTPHEADER =>
array("User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0")
I did not experiment with other/simpler User-Agent headers since this quick fix solved my problem.
According to the PHP manual, upload should be urlencoded:
CURLOPT_POSTFIELDS The full data to post in a HTTP "POST" operation.
[...] This parameter can either be
passed as a urlencoded string like 'para1=val1¶2=val2&...' or as
an array with the field name as key and field data as value. If value
is an array, the Content-Type header will be set to
multipart/form-data. As of PHP 5.2.0, value must be an array if files
are passed to this option with the # prefix. As of PHP 5.5.0, the #
prefix is deprecated and files can be sent using CURLFile.
So you might try with
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'xml=' . urlencode($xml));
and see what happens. Or, anyway, start with an empty or very simple FIELD to see if it at least arrives to the destination server.
Update
I've checked this setup on a test machine and it works. The problem is then likely not to be PHP or cURL side at all, at this point. Can you request a list of software/hardware updates on that machine and network in the last days?
Otherwise, I'd try to capture outgoing traffic so as to determine whether the request leaves the server (and the problem is in between, e.g. a misconfigured firewall: hence my inclusion of "hardware" in the change list), or doesn't leave the server at all. In this latter case the culprits could be:
updates to cURL library
updates to PHP cURL module and/or PHP binaries
updates to "software" firewall rules
updates to ancillary network libraries (unlikely; they should be HTTP agnostic and not differentiate a POST from, say, a GET or HEAD)
OK, as it turns out, a rather reluctant host recompiled Apache2 and PHP which has resolved the issue.
The host claims (their opening statement to my support ticket) that no updates to either Apache2 or PHP had been performed around the time the issue occurred.
the behavior was as such that it wasnt even acknowledging a CURL request that contained the POST commands. The target URL was never reached.
Thank you so much to all who provided their advice. Particularly Isemi who has gone to great lengths to find a resolution.