1

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); 
1
  • 504 Gateway Timeout is emmited by the backend server of this API not in the request, which is different, 408 Request Timeout. I guess the headers maybe be wrong, check the User-Agent, the token, or other config that Postman has and the curl isn't config with. Commented Oct 6, 2020 at 21:29

1 Answer 1

3

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);

Sign up to request clarification or add additional context in comments.

6 Comments

Even after setting FOLLOWLOCATION, I get the same result: almost infinite loading, then a 504 error in my browser. And the CURLOPT_HEADER just makes the cURL fail btw
@Thiago This option should list all headers sent & received. Make sure you use a sane environment. curl.haxx.se/libcurl/c/CURLOPT_HEADER.html ...and "just makes it fail" is not an error description at all, because it barely fails without a reason. If you just take a simple HTML form and post that, it should be testable in a web-browser. Improving the cURL error handling might also make sense, because you don't follow the default procedure there; var_dump($e) is useless.... use curl_error($ch), in order not to ignore eventual errors.
Also see developers.mercadolibre.com/listing-introduction ...the payload may be wrongful. Sorry, but I don't understand any of this and can only refer to: api.mercadolibre.com/items#options ... GET /items just gives me resource not found (likely because it expects a POST). Generally cURL just emulates a web-browser, that's why one can use a web-browser to know for certain what to emulate.
The point is that the code doesn't even hit the catch{ }, so the curl_error is useless as well; The "just makes if fail" happens when I add the CURLOPT_HEADER, it gives me the same loading forever then 504, even when the payload is right (by right I mean: works without the CURLOPT_HEADER) The documentation of the API is in portuguese, so its normal for you to not understand it. I need to catch those API errors because the client may commit mistakes sometimes, and giving 'em a "504 - Gateway timeout" page isn't good at all
Can you access any routes that use GET, eg. listing those items? An Exception is not necessary be thrown, but if there was an error, it can be obtained from the cURL handle. My code usually doesn't look much different (except the error handling), but I usually just call curl_init() and then set the URL along with the options. With option CURLOPT_HEADER enabled, you ordinary should get output similar to this: stackoverflow.com/a/3252889/549372 ...which is quite essential for debugging.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.