PHP cURL gives an error but works fine in POSTMAN - php

I have some problem(s) with PHP cURL. I tried to get data from the API using PHP cURL. This is my cURL code in PHP :
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://www.example.com/dos/AW/API",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "{\"Filter\" : {\"IsActive\" : \"True\",\"OutputSelector\" : \"Name\"}}",
CURLOPT_HTTPHEADER => array(
"API_ACTION: GetItem",
"API_KEY: MHlIARzQqxVpOg2dUxH4q9w7bx3pOL6K",
"Accept: application/json"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
?>
With that code I can get a response but the response contains some errors. I also tried using POSTMAN to check, and the API works fine as I got a successful response with the same data. My question is: "Is there anything wrong with my cURL code that would explain why I got an error when I used cURL and I got successful response in POSTMAN "?
I would appreciate if someone could help me with this.
Thank you very much.

given that you aren't showing us the successful postman request, we can't know for sure what errors you make, that said, you are making a couple of obvious mistakes here.
first off, when debugging curl code, use CURLOPT_VERBOSE , it gies you a lot of useful information when debugging your curl requests (and if you did this, you would probably notice how the Postman requests's content-type is completely different from curl's content-type http headers - more on this soon)
second, when you want a POST request, don't use CURLOPT_CUSTOMREQUEST, use CURLOPT_POST.
third, when passing a string to CURLOPT_POSTFIELDS, the content-type implicitly becomes Content-Type: application/x-www-urlencoded, unless you override it. and you are obviously NOT sending x-www-urlencoded data, but JSON-encoded data, so your content-type is all wrong, its supposed to be Content-type: application/json
fourth, you can hardcode the json if you want, but the code looks much prettier if you json_encode it
fifth, don't use setopt / setopt_array without checking the return type.
fixing all that, you'll end up with something like:
function ecurl_setopt_array($ch, array $options) {
if (! curl_setopt_array ( $ch, $options )) {
throw new \RuntimeException ( 'curl_setopt_array failed. ' . curl_errno ( $ch ) . ': ' . curl_error ( $ch ) );
}
}
$curl = curl_init ();
ecurl_setopt_array ( $curl, array (
CURLOPT_URL => "https://www.example.com/dos/AW/API",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_VERBOSE => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode ( array (
'Filter' => array (
'IsActive' => 'True',
'OutputSelector' => 'Name'
)
) ),
CURLOPT_HTTPHEADER => array (
"API_ACTION: GetItem",
"API_KEY: MHlIARzQqxVpOg2dUxH4q9w7bx3pOL6K",
"Accept: application/json",
'Content-Type: application/json'
)
) );
$response = curl_exec ( $curl );
$err = curl_error ( $curl );
curl_close ( $curl );
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
Edit: fixed the json data, when i wrote it, i didn't see that isActive is not an actual boolean, but the string literal True - i mistakenly encoded it as a json boolean true instead, sorry, fixed. (although i suspect it's supposed to be a boolean anyway, and that your original code just encodes it wrong, perhaps you should double check isActive's type in the api docs, assuming there is one)

#Antonio, Response you are getting is from the other end, might be you are missing something which restrict the processing of query at other end. try to print http_code, or use curl_getinfo to get complete information.
in case of response code is 200, then you may ask from another end to validate the request.
PS: not able to comment because of repo restrictions.

Related

cURL Access Denied in crawler PHP

I'm creating a crawler to capture some public information.
However, it is returning:
Access Denied
You don't have permission to access "http://www.americanas.com.br/" on this server.
Using Postman to test a request, cURL works perfectly. I even got the code generated by Postman (as shown below), but when I use it directly on my PHP server, return the error informed above.
My cURL code:
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://www.americanas.com.br/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"postman-token: 112ebf89-1bb7-aa7a-0645-cdeabcf96488"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if($err) echo "cURL Error #:" . $err;
else echo $response;
exit();
I found that there are sites with more complex locks. In these cases, it is necessary to use more complete crawler solutions.
The one I'm using and is working is Proxycawl (https://proxycrawl.com/).
Your postman is querying https://www.americanas.com.br/ while from the error message we can suppose that in your crawler you are querying http://www.americanas.com.br/

Why does my POST request time out in PHP using cURL, but not in Postman?

I have an auth.php file that should make a request to an API with some headers, data and stuff.
I tried Postman, and gave me a response almost immediately.
I copied the code (PHP > cURL) and tried it, and it would be waiting for MYPRIVATESITE.com for 30 seconds (I set the timeout to that), and then just cURL ERROR: TIMED OUT (or something like that).
What did I do wrong? It works with e.g. postman, so why not my website?
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://discordapp.com/api/v6/oauth2/token",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "client_id=PRIVATEID&client_secret=PRIVATEKEY&grant_type=authorization_code&code=$code&redirect_uri=https%3A%2F%2Fkanebot.epizy.com%2Fauth.php&scope=identify%20guilds&undefined=",
CURLOPT_HTTPHEADER => array(
"Content-Type: application/x-www-form-urlencoded",
"cache-control: no-cache"
)
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
Note: The PRIVATEKEY and PRIVATEID are there, I just remove them because I don't want anyone else to steal it. It's defined, and it worked (read up).
The $code is also defined.
You are missing the & operator in your POSTFIELDS between the client_secret and the grant_type
try to add the & and see if its working after (it will sure solve one of the problems you have)
client_id=PRIVATEID&client_secret=PRIVATEKEYgrant_type=authorization_code&code=$code&redirect_uri=https%3A%2F%2Fkanebot.epizy.com%2Fauth.php&scope=identify%20guilds&undefined=

How to set curl request properly in php laravel 5.5

I am trying to make a curl request!
Here I can make this request using postman and I am getting response perfectly using postman:
My Body parameter is: sub_domain
and my header is x-api-key value is something ZYWHUYAOSYSOASYYY
Ind i can get response perfectly!
But here want to make curl request on my end:
My Controller Code:
public function curlPost()
{
$data1 = [
'sub_domain' => 'value_1',
];
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://uwxcdwsc0k.execute-api.us-east-
1.amazonaws.com/prod/domain",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30000,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode($data1),
CURLOPT_HTTPHEADER => array(
// Set here required headers
"x-api-key: KiZTkTO9Ex2ZCOr7xmYRA4bInlJc9kVNrVN2INrc",
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
print_r(json_decode($response));
}
}
and my Routes/api.php:
Route::post('subdomain', 'ApiController#curlPost');
and when i hit post request using postman i get error
stdClass Object
(
[code] => [422] Unprocessable Entity
[message] => sub_domain is required
)
Your help will be highly appreciated!
Add this to your header array,
'Content-Type:application/json'
Make the $data an array as below:
$data1 = array(
'sub_domain' => 'value_1'
);
Cheers

PHP curl - been getting spammed with these warnings recently, out of nowhere

private function _curl($url, $values)
{
$curl = curl_init($url);
$options = array(
CURLOPT_VERBOSE => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => http_build_query($values),
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_TIMEOUT => 10,
CURLOPT_HTTPHEADER => "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
//CURLOPT_SSL_VERIFYPEER => false //for dev
);
curl_setopt_array($curl, $options);
$rep = curl_exec($curl);
parse_str($rep, $response);
curl_close($curl);
return $response;
}
So that's the code I'm using, and I keep getting these warnings:
PHP Warning: curl_setopt_array(): You must pass either an object or an array with the CURLOPT_HTTPHEADER, CURLOPT_QUOTE, CURLOPT_HTTP200ALIASES and CURLOPT_POSTQUOTE arguments
This code has been working fine for years and is only suddenly causing issues.
I would just pass those parameters, but I'm wondering why this suddenly isn't working, and it used to work correctly? And is there a way to get around this without passing the parameters? I also can't seem to find any documentation anywhere saying these parameters are needed...
The issue was the fact that CURLOPT_HTTPHEADER needs to be an array, as follows:
CURLOPT_HTTPHEADER => Array("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")

What is the postman-token header attribute in generated code from Postman?

I have been using postman to explore a REST interface. When using Postman's code generation feature, regardless of which programming language I select, Postman will always add a postman-token attribute in the header. Why is it there?
See for example PHP Curl:
<?php
$curl = curl_init();
curl_setopt_array($curl, array(CURLOPT_URL => "https://myURL.com,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"authorization: Basic abcdefghijklmnop",
"cache-control: no-cache",
"postman-token: wt53gwg-e9bb-645d-g53d-e42f8765aut0"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
This is primarily used to bypass a bug in Chrome. If an XMLHttpRequest is pending and another request is sent with the same parameters then Chrome returns the same response for both of them. Sending a random token avoids this issue. This can also help you distinguish between request on the server side.
See docs/settings postman.

Categories