PHP - curl localhost connection refused - php

Explanation
I made a simple REST api in Java (GET).
Postman works (both localhost and IPv4)
curl from command line works (both localhost and IPv4)
External request from a different city works (IPv4)
Expected
To have PHP curl work on the localhost
Actual
For some reason PHP curl on IPv4 works, but localhost does not work
PHP curl output error
Failed to connect to localhost port 8080: Connection refused
curl error: 7
Code
$url = 'http://localhost:8080/api/user';
$curl = curl_init($url);
echo json_decode(curl_exec($curl));
I have tried (from the top of my head, no specific order)
curl_setopt ($curl, CURLOPT_PORT , 8080);
curl_setopt($curl, CURLOPT_POST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

For those ones who are using Docker, Vargant and so on.
You got Failed to connect to localhost port 8080: Connection refused error, because you are trying to connect to localhost:8080 from inside virtual machine (eq. Docker), this host isn't available inside the Docker container, so you should add a proxy that can reach a port from the out.
To fix this issue add the next line of code after your curl_init():
curl_setopt($ch, CURLOPT_PROXY, $_SERVER['SERVER_ADDR'] . ':' . $_SERVER['SERVER_PORT']);
Here is a full example:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $APIUrl);
if ($_SERVER['HTTP_HOST'] == 'localhost:8080') {
// Proxy for Docker
curl_setopt($ch, CURLOPT_PROXY, $_SERVER['SERVER_ADDR'] . ':' . $_SERVER['SERVER_PORT']);
}
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if (curl_errno($ch)) {
$error = curl_error($ch);
}
curl_close($ch);

I'm not sure if this counts as an answer but I just restarted the linux VM and now its working...

Not sure if it's still usefull for you, but I've faced with almost same problem. I've started php server using php -S localhost:5500 or with VS-code extention, and try to connect via curl to same host, and it taken almost infinite time with no response. Solution was simple (if you understand russian, or can use translator you can find full article here).
So, from this article:
This script will not work with the default WPN-XM v0.8.6 setting because there is only one php -C gi process listening in the background, but your example requires (at least) two of them. php -C gi is already in use by the script making the curl request and therefore Nginx cannot redirect it to php -C gi. This means that you will first come across a blank page with a loading indicator and then remove the connection timeout.
The main problem is that php -C gi doesn't automatically spawn new processes (if needed). The issue is discussed here: https://github.com/WPN-XM/WPN-XM/issues/323
So the solution for me was to create another php server with a different port (for example 5500 and 5550) and everything started working.

Related

Can't cURL to other server from web server, but can from localhost

I have two servers, one is my webserver, for my website, and the other one is my discord bot hosting server. My setup is when a certain action occurs on the webpage, it'll use cURL to post to the node.js server (the discord bot), which would then return some data.When it was in development and I was creating it on my localhost, it worked perfect (both servers were locally hosted). When I take the servers and run them on their respective services, I am given a connection refused error from cURL, same with file_get_contents().
$ch = curl_init();
curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, 'http://51.161.93.27:8109/');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
$data = curl_exec($ch);
echo "<pre>";
var_dump( curl_getinfo($ch) ) . '<br/>';
echo curl_errno($ch) . '<br/>';
echo curl_error($ch) . '<br/>';
curl_close($ch);
If I run this exact code from localhost instead of the webserver, it works and gets the data. On the webserver I can not post or get.
On the webserver, if I remove the port from the CURLOPT_URL, it'll connect to the main ip and return stuff. Same if I put www.google.com. This means cURL works, just can't connect to the port itself.
Note, the specific port is being run with the node.js http module along with express.
The webserver is being run from namecheap, and using cpanel. The discord bot hosting service is called pebblehosting.
Feel free to use the address, http://51.161.93.27:8109/ to find some more information, its the bot address. If able to succesfully get data from it, it should display a json string with a message stating {"status":"fail. You already have a ticket open"}.
I also connected to the address from services like ping.com and was able to connect.
I have spent all day trying to find a solution, but couldn't find anything.

PHP curl unable to access other servers via VPN

I have a server connected to my company via OpenVPN and I am trying to retrieve JSON from another server using PHP's curl command.
Running the most stripped back version of the code in PHP's interactive mode from the command line (php -a), works fine:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'status.int.companyname.com');
curl_exec($ch);
{...expected json response after 2 seconds}
Howver when I run this from within Apache, the script will just hang.
Setting some timeouts and outputting the error
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
echo 'Error: '.curl_error($ch);
Gives the error as
Error: Resolving timed out after 10517 milliseconds
Initially I thought this was a DNS-related issue, but changing the URL to use the IP address or specifying the address to resolve to
curl_setopt($ch, CURLOPT_RESOLVE, [ 'status.int.companyname.com:80:10.10.0.5']);
yeilded a connection error:
Error: Connection timed out after 10001 milliseconds
My next thought was that Apache was using the wrong interface. The VPN is the default gateway, so works fine with everything else but I tried forcing it with
curl_setopt($ch, CURLOPT_INTERFACE, '10.33.0.105');
This made no difference. After reading around a few other posts, I tried adding the following in various combinations but it made no difference.
curl_setopt($ch, CURLOPT_DNS_USE_GLOBAL_CACHE, false);
curl_setopt($ch, CURLOPT_DNS_CACHE_TIMEOUT, 2);
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
file_get_contents has the same problem
I don't inderstand it. Curl on the command line works and PHP in interactive mode work fine. It just doesn't work when the PHP script is executed via Apache.
Other things I've tried:
starting Apache after the VPN is connected
setting Apache to only bind to IPv4
Resolv.conf contains one nameserver, which is the correct one for the company VPN
The differences between the CLI and Apache versions of php.ini are as expected:
-disable_functions =
+disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,
-expose_php = On
+expose_php = Off
-memory_limit = -1
+memory_limit = 128M
Has anyone seen this before? I've lost a few hours of my day on this now and it's driving me mad!
Thanks

PHP curl call not working when the caller script is called from outside the LAN

So I am encountering a strange situation with a php curl request.
It works perfectly when the script is called from the same local network as the server which is running it but when somebody calls it from outside is not working anymore.
This is my code:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, ROOT_DIR."directory/someScript.php");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
$output = curl_exec($ch);
curl_close($ch);
When I run someScript.php manually even from outside the LAN it works just fine. The issue occurs only when it I try to run it by calling it with curl via another php script.
Anybody have any idea? The curl library is enabled. And both scripts are on the same server.
I am using port forwarding on port 80 to make the server visible in the Internet.
I decided to post the solution in case somebody else has the same problem.
In the end I found the cause for this. The problem was that I was calling the script using the external IP instead of the internal one. Further more because of this XAMPP redirected the call to its default page and because I didn't use the output I did not noticed that.

Capturing cURL trace using Fiddler2 (PHP)

As recommended by my DocuSign account manager, I am using Fiddler2 to capture the necessary trace for API certification. I am unable to retrieve the trace from the DocuSign domain and have narrowed it down to the fact that these are cURL calls.
According to Fiddler2, http://fiddler2.com/documentation/Configure-Fiddler/Tasks/ConfigurePHPcURL, the advice is to add the following to code:
curl_setopt($ch, CURLOPT_PROXY, '127.0.0.1:8888');
where $ch = curl_init().
I've also tried
curl_setopt($curl, CURLOPT_PROXY, '127.0.0.1:8888');
Still no dice. I only get traffic from my application site. The following is all of my curl code:
$url = "https://demo.docusign.net/restapi/v2/login_information";
$curl = curl_init($url);
$ch = curl_init();
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("X-DocuSign-Authentication: $header"));
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($curl, CURLOPT_CAINFO, getcwd() ."/**the cert info");
curl_setopt($ch, CURLOPT_PROXY, '127.0.0.1:8888');//allows fiddler to see requests
$json_response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
It's definitely talking to the DocuSign domain as my application is working, I'm just trying to get the trace. Any help is appreciated.
fiddler is client side program, it cannot see server traffic to other servers only traffic between client and server.
Unless your server is running locally (on the same computer that you are running fiddler) using 127.0.0.1 this will not work as 127.0.0.1 is the loopback ip for the computer, in this case the server would be trying to use itself as a proxy (which would be ok if the server computer itself was the one running fiddler). You need to change the ip to the computer running fiddler and make sure the server can access that port.
I was facing the exact same scenario, and I used a protocol analyzer such as Wireshark or TCPDUMP to see HTTP traffic at network level.
Of course the server needs to be running locally. Bellow you can find a screenshot example of traffic capture where you can clearly see the HTTP GET going out.

PHP CURL Error - curl: (56) Recv failure: Connection reset by peer

basically, this error only occurs in CURL
curl: (56) Recv failure: Connection reset by peer
But when I visit it directly the link directly on my browser, it works!
What are your recommendations on fixing this one or the cause of this error?
Note: the server is coded in ASP and it only occurs on one API Call
I resolved this issue by removing whitespace characters from the URL. In my situation, it was the proxy server that was erroring out, not the web server.
In PHP:
curl_setopt($ch, CURLOPT_URL, trim($url));
I remember facing the same issue a long time back. While I don't remember what exactly sorted out the issue, I remember trying the following:
I was trying to pass the query parameters in the URL directly and I tried passing through POST method
I tried using a proxy with curl to see if I was possibly being blocked by the other server
I believe I also asked my host to look into it and they made some Apache setting changes
I had similar problem with this code:
$url = "http://xxx.xxx.xxx.xxx";
$ch = curl_init();
curl_setopt($ch, CURLOPT_PORT, 44455); //Set the port to connect to
//curl_setopt($ch, CURLOPT_RETURNTRANSFER, 44455);
curl_setopt($ch, CURLOPT_URL, $url);
echo $xml = curl_exec($ch);
if(curl_errno($ch))
{
echo 'error:' . curl_error($ch);
}
curl_close($ch);
Got it solved by disabling this:
//curl_setopt($ch, CURLOPT_RETURNTRANSFER, 44455);

Categories