8

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);
4
  • @Calos sorry I'm not sure what you mean, but I'm using a tomcat local server, spring boot application Commented Feb 4, 2020 at 3:06
  • 1
    @Calos I actually disabled the fiewall while trying to fix this, didn't work, I have a question, if its not listening why does postman and command line curl work on localhost? just php curl doesn't Commented Feb 4, 2020 at 3:20
  • @Calos It's been there since the beginning, I mentioned both of them right at the top of my post Commented Feb 4, 2020 at 3:57
  • You should not switch off CURLOPT_SSL_VERIFYHOST or CURLOPT_SSL_VERIFYPEER. It could be a security risk! Here is how to get the certificate bundle if your server is missing one Commented Feb 8, 2020 at 17:49

4 Answers 4

26

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);
Sign up to request clarification or add additional context in comments.

2 Comments

That's a very good workaround for Docker.
It doesn't work for me. I got Failed to connect to 172.18.0.3 port 8080: Connection refused which has IP and port of server inside Docker. I call API of a container from another container. They run in different ports.
1

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

2 Comments

It actually counts as not reproducible. We usually delete such questions unless you think that this problem is going to happen to other people and this simple suggestion will help them too.
@Dharman I agree, this might not help anybody, should I delete it?
0

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.

Comments

0

I also add here something for those ones who are using Docker:

If having a default web app and an API, of course these should be two different services.

Here's a docker compose example:

version: '3'
services:
    default:
        container_name: web_app
        build: 
            context: ./
            dockerfile: ./default_page/Dockerfile
        volumes:
            - ./default_page:/var/www/html
        ports:
            - 8080:80
        networks:
            - my-network
    api:
        container_name: api
        build:
            context: ./
            dockerfile: ./default_page/html/public-html/api/Dockerfile
        volumes:
            - ./default_page/html:/var/www/html
        ports:
            - 3000:80
        networks:
            - my-network

networks:
    my-network:
        driver: bridge

I'm having this folder structure with default_page/html, so I can easily FTP deploy with a non public folder (DEV shared hosting fail 😅).

Now PHP curl is possible like that:

$apiUrl = "http://api/public-html/user"; // whatever endpoint
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $apiUrl);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);

Please check here as well that I have this public-html, which is unnecessary for other cases.

PS: sorry for being lazy and not provide an answer with clean folder structure. Of course in a usual environment and not having to few money for a real server, the web-app and the api should be in a separate folder.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.