cURL makes page load forever, then gateway timed out - php

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

The API probably sends HTTP302 in between and if so, you'd either need two requests ortell 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);

Related

PHP / Curl Incoming Webhook to MS Teams doesn't work all of the time

I am using an incoming webhook on a web app to post some data to teams. I got this working in CURL after looking up some implementation methods, but it should be noted I have no experience in CURL. The thing is, it works about half the time, then the other half this comes up in the error log:
[01-Feb-2021 09:00:59 Europe/London] Error: Could not resolve host: outlook.office.com
Was hoping someone can take a look and see if there is something obvious I am doing wrong. This is the code used in my PHP file (with the webhook ID removed for privacy)
// Generated by curl-to-PHP: http://incarnate.github.io/curl-to-php/
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt($ch, CURLOPT_URL, 'webhook-id-here');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"text\": \"$teamsMessage\"}");
$headers = array();
$headers[] = 'Content-Type:application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
error_log("Error: " . curl_error($ch), 0);
}
curl_close($ch);
Looks like a DNS problem. Could not resolve host: outlook.office.com.
Maybe any firewall involved in blocking that? Remove CURLOPT_SSL_VERIFYPEER and CURLOPT_IPRESOLVE.
Try this simplified solution, which works well for me. I am using JSON header instead of form encoding.
// Paste the URL here
$url = 'https://outlook.office.com/webhook/XXX';
// Use the text encoded as MARKDOWN.
// Any markdown character needs to be escaped!
$body = ['text' => 'Hello World'];
$curlHandle = curl_init($url);
curl_setopt_array($curlHandle, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($body)
]);
$response = curl_exec($curlHandle);
curl_close($curlHandle);
if ($response !== '1') throw new Exception('No Response from MS incoming webhook API');

PHP CURL returning 301 Location

My curl php code is returning 301 and i can't print out what the curl returned.
this is my code:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://subdomain.thinkific.com/api/public/v1/users/3418346");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
$headers = array();
$headers[] = "X-Auth-Api-Key: myapikey";
$headers[] = "X-Auth-Subdomain: subdomain";
$headers[] = "Content-Type: application/json";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
var_dump($result);
Here is what it returned:
string(142) "301{"Location"=>"https:subdomain.thinkific.com/api/public/v1/users/3418346", "Cache-Control"=>"no-cache"}#"
i have tried json_decode the result to print it, still the same. as well as i also tried those:
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_NOBODY, 1); //this one returned string(0) without 301
I need to know if the error is from my server or it has something to do with my code. ( i did not share api key and subdomain for privacy sorry).
The 301 response code is the following :
The HTTP response status code 301 Moved Permanently is used for
permanent URL redirection, meaning current links or records using the
URL that the response is received for should be updated. The new URL
should be provided in the Location field included with the response.
SO it means that you're requesting a resource that has been moved (the url changed) and you should retry the request with the newly provided URL !

Send ajax request through CURL

An API request needs to be sent. For some reason, the server is blocking CURL request, but it approves an XHR ajax request. I could send an ajax request, but another problem arises - Mixed content my website is served over HTTPS but the request that needs to be sent is over HTTP so I cannot use ajax.
I am looking for a way to simulate ajax request through CURL, in some way, trick the server to believe that the CURL request is indeed an ajax request.
Here's what I have tried.
This is my CURL request.
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Linux x86_64)');
curl_setopt($ch, CURLOPT_REFERER, 'server's url');
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Accept:application/json, text/javascript, */*; q=0.01',
'Accept-Encoding:gzip, deflate',
'Accept-Language:en-US,en;q=0.9',
'Connection:keep-alive',
'Content-Type: application/json; charset=utf-8',
'X-Requested-With: XMLHttpRequest',
'__RequestVerificationToken: $token'
));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_COOKIEJAR, base_path().'/cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, base_path().'/cookies.txt');
$buffer = curl_exec($ch);
if(curl_error($ch))
{
$buffer = curl_error($ch);
}
curl_close($ch);
return $buffer;
This curl request is blocked
But, this ajax request goes through my localhost, but since my live website uses HTTPS I cannot really use it.
$.ajax({
type: "get",
xhrFields: { withCredentials:true },
url: http://apiendpoint.com,
success: function(data)
{
// console.log(data);
}
})
in chrome, you can copy a working curl expression from developer toolbar. Try with that one from cli. If that works, you can figure out which parts are required and which parts are not. Then you can transcript it to php.
If you have doubts if the same thing happens from php than from curl, just try it with requestbin.
I think it is possible the header for token may not be what you think it is, since given $a==1, '$a' converts to $a, but "$a" converts to "1" (notice single quotes vs double quotes).
in your example, try replacing:
'__RequestVerificationToken: $token'
with:
"__RequestVerificationToken: $token"
and let us know if that solves the problem.
Consider using passthru("curl command here..."); using the suggestion from lintabá
You can use 2-stage request
1 curl .... -c ${cookie_file}
2 curl .... -b ${cookie_file} -c ${cookie_file}
This should work.
first is basicly gets the cookie with session id
2nd do the real request

PHP cURL Put, no permission (403 forbidden)

I made a script that uses the Mobile.de API.
It worked fine on their test environment, only difference with the live environment is the proxy. So in my cURL I removed the proxy.
For any POST call this works just fine, but for my PUT call it doesn't work at all.
So let's say I sent the following with for example Postman:
PUT /seller-api/sellers/123/ads/456
Host: services.mobile.de
Content-Type: application/vnd.de.mobile.api+json
Authorization: Basic abcdef12345=
And I put in the right JSON, it works just fine.
And this is the script I use in PHP:
function updateVehicle($seller, $voertuig_id, $json) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://services.mobile.de/seller-api/sellers/' . $seller . '/ads/' . $voertuig_id);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_USERPWD, USERNAME . ':' . PASSWORD);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Host: services.mobile.de',
'Content-type: application/vnd.de.mobile.api+json'
));
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
In return I get the 403 forbidden. 'You don't have permission to access /seller-api/sellers/123/ads/456 on this server.'
I already printed out al curl info and saw that all the headers are there and everything seems just fine, but why don't I have permission.
Contacted Mobile.de already but they say it's something in my code.
So after much debugging I found out it was a space after the $voertuig_id that got me an 403 forbidden error. :S

Send and Receive JSON using an https curl_exec call in PHP

I'm trying to make a curl call using PHP. My project has a flow like this
I redirect user to the server.
User uses the services and the server redirects him to a page on my application.
I would like to make a server to server call at this point to verify certain details.
Point to be noted - I post JSON data as well as receive JSON data as response.
I have tried this. I am able to send data but don't get any response.
Is this correct?
Please help!
$data = array("One" => "Onedata", "Two" => "Twodata");
$JsonData = json_encode($data);
$ch = curl_init('https://exampleurl');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $JsonData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($JsonData))
);
$result = curl_exec($ch);
As you mention in the comment:
The problem is with SSL verification of the host. It takes some effort (see http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/) to setup SSL correctly, so a workaround is to add the following two options:
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
Try to use the below code which works for me. and make sure the json_url is correct. When you run it on the browser you should get an output. Before try it using CURL, run in on the browser and see whether you get the output you want.
$json_url ='https://exampleurl';
// Initializing curl
$ch = curl_init( $json_url );
// Configuring curl options
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array('Content-type: application/json')
);
// Setting curl options
curl_setopt_array( $ch, $options );
// Getting results
$results = curl_exec($ch); // Getting jSON result string
$json_decoded = json_decode($results);

Categories