phpcurlhttp-status-code-504

cURL makes page load forever, then gateway timed out


I'm working with a third party API, and it returns 400 HTTP STATUS when you make a mistake. When using POSTMAN, the 400 HTTP error page shows as expected, but when using PHP's cURL, the page just loads for about a minute, then it gives me a "504 - Gateway timeout", and I need to close the browser to be able to access the page again. When the cURL request is valid (the API returns a 200 OK) it works normally.

My question is, why is cURL giving the 504 error instead of 400? And why is it ignoring CURLOPT_CONNECTTIMEOUT and CURLOPT_TIMEOUT?

Below is my cURL code (both $token, $payload and $config variables are declared and valid):

$ch = curl_init("https://api.mercadolibre.com/items?access_token=$token");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    "User-Agent: Alcavie/" . $config['version'],
    "Accept: application/json",
    "Content-Type: application/json",
    //"Accept-Encoding: gzip, deflate, br",
    //"Connection: keep-alive"
));

$error = false;
try{
    $result = curl_exec($ch);
    $resultJson = json_decode($result);
}catch(\Exception $e){
    var_dump($e);
    $error = true;
    exit;
}
curl_close($ch);

Solution

  • The API probably sends HTTP302 in between and if so, you'd either need two requests or
    tell cURL to follow the redirect with curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    HTTP504 means that the client didn't react in a timely manner upon the previous HTTP header;
    there may be other causes for HTTP504, but it is one of the most common. Postman is insufficient to test this properly (I don't use it at all); better use a web-browser, hit F12 and tick the "preserve logs" checkbox... then you can clearly see which HTTP headers are being sent in succession.

    Also useful to debug this would be: curl_setopt($ch, CURLOPT_HEADER, true);