'Laravel Lumen Guzzle times out with no obvious reason why, error code 28 curl

I'm currently working on a Laravel 8 project, I have two projects:

  1. A Laravel 8 project used as an API, it exposes some endpoints
  2. A Laravel Lumen 8 project which runs on it's own domain.

Both have Cors enabled, and both run on the same domain, I'm having issues with Guzzle in my Lumen project connecting to an endpoint that exists on my Laravel API, here's the scenario and request flow:

  1. A request comes in to: /hub/microservice/fudge-api-reports on the Laravel api, this is it's controller method:
/**
 * Route the microservice
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\Response
 */
public function microservice(Request $request, $service)
{
    $validator = Validator::make($request->all(), [
        'endpoint' => 'required|string',
        'method' => 'required|string|in:post,get',
        'data' => 'nullable|array'
    ]);

    if ($validator->fails()) {
        return response()->json([
            'message' => "One or more fields has been missed or is invalid.",
            'errors' => $validator->messages()
        ], 400);
    }

    $microservice = Microservice::where('microservice', $service)->first();

    if (!$microservice) {
        return response()->json([
            'message' => "The microservice you're trying to access is invalid or doesn't exist"
        ], 404);
    }

    // auth
    $auth = 'Bearer ' . $microservice->hub_access_token;

    // the url
    $url = $microservice->hub_domain . $request->input('endpoint');

    // define how to communicate with the microservice
    if ($request->input('method') == 'post') {

        if ($microservice->hub_access_token) {
            $response = Http::timeout(60)->withHeaders([
                'Authorization' => $auth
            ])->post($url, $request->input('data'));
        } else {
            $response = Http::timeout(60)->post($url, $request->input('data'));
        }

    } else {

        if ($microservice->hub_access_token) {
            $response = Http::timeout(60)->withHeaders([
                'Authorization' => $auth
            ])->get($url);
        } else {
            $response = Http::timeout(60)->get($url);
        }

    }

    // the response from the microservice
    return response()->json($response->json(), $response->status());
}
  1. The request then (based on the endpoint and method) goes to the microservice which runs on it's own domain, mine is: http://localhost:8001/, my URL would be a GET request, and would have an access token, so it makes it into the else statement above and into the first if, e.g: http://localhost:8001/api/reports?report=MyReport and has a token as the header.

  2. The request comes into the fudge-api-reports Laravel Lumen project, and goes to a controller method, but first passes through my BeforeMiddleware where it performs a "log in" request back to the Laravel API to authenticate and check the abilities, this part of the middleware is:

<?php

namespace App\Http\Middleware;

use Closure;
use GuzzleHttp\Client;

class BeforeMiddleware
{
    /**
     * Request attributes
     *
     */
    public $attributes;

    /**
     * Get API url
     */
    protected function getApiUrl()
    {
        return rtrim(config('fudge.fudge_api_domain'), '/');
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next, $ability)
    {
        $api = $this->getApiUrl();

        $token = $request->input('token');
        if (!$token && $request->header('Authorization')) {
            $token = explode(' ', $request->header('Authorization'))[1];
        }

        // TODO: this part appears to ALWAYS time out, despite
        // http://localhost:8000/api/hub/login working just fine via Postman
        $client = new Client([
            'base_uri' => $api,
            'timeout' => 5
        ]);

        $res = $client->request('POST', '/api/hub/login', [
            'token' => $token,
            'ability' => "reports:$ability"
        ]);

        // the response
        $res = $res->json();
        $hasAbility = isset($res['has_ability']) && !empty($res['has_ability']) ? $res['has_ability'] : false;

        // not authorised
        if (!$hasAbility) {
            return response()->json([
                'message' => "You aren't authorised"
            ], 200);
        }

        // add the hub's user to the request
        $request->attributes->add(['has_ability' => $hasAbility]);

        // Post-Middleware Action
        return $next($request);
    }
}
  1. If the Hub log in is successful, then a has_ability is returned with the value of true back to the the middleware, which then goes through the controller method and finally returns the response back to the initial request of: /hub/microservice/fudge-api-reports

My issue

in my BeforeMiddleware my Guzzle POST request always fails, and never returns a response, it always seems to time out accessing my /api/hub/login endpoint that exists in my Laravel project.

It works perfectly fine through Postman, and Cors is enabled, why would this always timeout in the context of the Middleware, what am I missing?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source