Server accessible to proxies but not cURL? - php

I have tested my local server with a proxy and my friends can all load the url in their browser, but when I try to use cURL on a separate server, it fails connecting.
Here is the URL, it loads on both my browser and using my friend's internet:
http://pc.stephen3.com:8080/gameq.php
Here is the code I am using on a separate server, it successfully retrieves all other URLs (like google and yahoo)
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://pc.stephen3.com:8080/gameq.php");
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$err = curl_error($ch);
$resp = curl_exec($ch);
echo $resp;
echo $err;
But it returns nothing on my home server's url, and
curl_error($ch);
(did say, now says nothing) "couldn't connect to host"
Any ideas what it could be? The url works everywhere, but in cURL. The code works everywhere but with the URL.
EDIT: It occurred to me that it may be because of the outbound traffic on my external server being on port 8080 instead of 80 for regular servers, will have to test if my hoster allows curl on other ports.

Maybe you have to remove port number from URL and configure CURLOPT_PORT option.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://pc.stephen3.com/gameq.php"); // port removed
curl_setopt($ch, CURLOPT_PORT, 8080); // that line added
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$err = curl_error($ch);
$resp = curl_exec($ch);
echo $resp;
echo $err;
You may also use curl_getinfo($ch) function for more debug information.
$report=curl_getinfo($ch);
echo "curl_getinfo returned: <br>".$report;

It turns out my host (iPower) restricts cURL to port 80 :(
EDIT : I found out that support lied, saying only port 80 is allowed. In fact, they allow port 80 AND 990 (SSL) but you can use port 990 without actually having SSL on. Works perfectly.

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 localhost connection refused

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.

error: couldn't connect to host via CURL on same domain

I have a URL - http://www.xxx.xxx.xxx/
This URL, I'm able to open through the browser. I'm even able to call this URL via cURL from my machine, but when I'm calling it from the code on the same server and domain, it gives me an error - error: couldn't connect to host
Following is my code -
function get_xml_via_curl($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
echo $url;
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
/*curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);*/
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
$returned = curl_exec($ch);
if(curl_errno($ch)) {
echo 'error: ' . curl_error($ch);
}
curl_close($ch);
// $xml === False on failure
$xml = simplexml_load_string($returned);
return $xml;
}
Like I said, on localhost this works. I can directly open the URL via the browser. But when I deploy the code on the same server and try calling via cURL, it gives me an error - error: couldn't connect to host
Updated Code -
I modified the code on my server to -
function get_xml_via_curl($url) {
$url = " http://www.xxx.xxx.xxx.xxx/";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
$returned = curl_exec($ch);
if(curl_errno($ch)) {
echo 'error: ' . curl_error($ch);
}
curl_close($ch);
$xml = simplexml_load_string($returned);
return $xml;
}
And the error from curl changes to following -
error: Protocol http not supported or disabled in libcurl
Your updated code is not working because of the white space before http in $url = " http...
The original code is probably not working because of some firewall or nameserver issue. Try to visit the URL you want to load directly in a browser ON THE SAME SERVER. That will probably fail too.
You need to fix the server to accept requests from the localhost.
What can also help you on your way is to check the web server and firewall log files. See why the requests are being declined. And even temporarily just disable the firewall to rule it out.
I have faced the same, PHP curl throwing 'Connection timeout error' because of same domain and tried all other options, but nothing worked out.
Finally I got the answer and fixed it. Just run below command (ubuntu)
# sudo ifconfig lo up
For Cent OS:
# sudo ip link set lo up
# sudo ip addr show
"lo" is the loopback interface. This is a special network interface that the system uses to communicate with itself.
try:
$url="//your url";
echo get_xml_via_curl($url);

cURL request using socks5 proxy fails when using PHP, but it works through the command line

cURL + proxy noob here, having a hard time. I'm having trouble trying to retrieve a web page from a remote secure server via a proxy. Everything has apparently been set up correctly by a remote dev, such that the following command line instruction works and returns what we're looking for:
curl -k --socks5-hostname localhost:xxxx https://hostname/
However, the following PHP does not echo the requested webpage. Instead it echoes the error 'Couldn't resolve host name':
$proxy = 'localhost:xxxx';
$url = 'https://hostname/';
//$proxyauth = 'user:password';
$ch = curl_init();
curl_setopt($ch, CURLOPT_PROXY, $proxy);
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
//curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxyauth);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_URL, $url);
$curl_scraped_page = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($error)
echo $error;
elseif ($curl_scraped_page)
echo $curl_scraped_page;
If the $url is changed to a public page, such as Google, the request is successful and everyone is happy.
The connection requires an SSH tunnel if that changes anything at all. The tunnel is open and functioning, as proven by the command line request succeeding.
Is there something obvious that is being missed here?
You need to set option CURLOPT_PROXYTYPE to CURLPROXY_SOCKS5_HOSTNAME, which sadly wasn't defined in old PHP versions, circa pre-5.6; if you have earlier in but you can explicitly use its value, which is equal to 7:
curl_setopt($ch, CURLOPT_PROXYTYPE, 7);
In the option CURLOPT_PROXYTYPE you need to set CURLPROXY_SOCKS5_HOSTNAME option instead of CURLPROXY_SOCKS5.
In this case, the DNS query (for hostname resolving) will be sent to SOCKS proxy and not resolved in the local network.
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5_HOSTNAME);
This constant available since PHP 5.5.23 and PHP 5.6.7 and cURL 7.18.0, so you can simply use it.

Joomla site on LAMP server behind proxy cannot access HTTP resource stream

Setup:
1. Joomla 1.5 website on a LAMP server (CentOS 5.2/Apache 2.2/PHP 5.2.9/mysql 5)
2. Joomla module for currency conversion added. Module uses google finance to convert currency
3. LAMP stack resides in the intranet behind a proxy. The server environment variables for http_proxy, yum.conf proxy have been setup, and kernel successfully updated.
4. phpinfo() clearly shows curl is installed
5. module mentioned in '2.' allows 3 methods to connect to google finance, fread(), file_get_contents() and using the cURL libraries. As the box is behind a proxy, only the cURL libraries method should work.
Problem:
on a WAMP stack, the curl library method works fine. On the lamp stack, however, the module is unable to communicate with google finance, and throws an error mentioning connect timed out. Here's some code to make it clearer.
if (isset($_GET['process'])) {
$url = "http://finance.google.com/finance/converter?a={
$_GET['a']}&from={$_GET['from']}&to={$_GET['to']}";
$app->get_page($url);
$data = $app->process();
}
function get_page($url) {
if ($url!='') {
echo $url;
$ch = curl_init ();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, $this->binary);
$this->html = curl_exec($ch);
curl_close($ch);
}
}
I even tried adding a curl_setopt($ch, CURLOPT_PROXY,'10.x.xx.xx:8080'); after curl_init(), to no avail. I've compiled apache with libcurl and php enabled, and I need to know the following:
1. How to instruct php to route outgoing requests(streams) through the proxy?
2. Do I need to configure cURL (libcurl) with the proxyname and port?
3. I've switched iptables off, so the linux firewall is not in the picture anymore, is there anything else I need to do to allow outgoing requests?
4. I've setup the proxy so that my LAMP stack is unblocked for all content, cURL works off the command line, but not from php/apache. What am I missing? Any environment variables? Any switches?
Thanks in advance for your time.
Shrinivas
Here's an example using a local SOCKS5 proxy on port 1090:
<?php
$url = 'www.whatismyip.com/automation/<your unique whatismyip hash>';
function get_page($url, $proxy=true) {
if ($url!='') {
$ch = curl_init ();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
if ($proxy) {
curl_setopt($ch, CURLOPT_PROXY, 'localhost');
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
curl_setopt($ch, CURLOPT_PROXYPORT, 1090);
}
$html = curl_exec($ch);
curl_close($ch);
return $html;
}
}
var_dump(get_page($url));
var_dump(get_page($url, false));
You'd probably want to use curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); and curl_setopt($ch, CURLOPT_PROXYPORT, 8080); instead.

Categories