I need to PUT some json data to an API endpoint, which works as expected via command line curl, but not via php curl and I don't have any idea, why it doesn't.
my command is
curl -v --insecure --request PUT --url <https://blabla/blablabla> --user 'username:password' --header 'Content-Type: application/json' --data '<valid json data>'
but it doesn't work this way within php:
// get cURL resource
$curl = curl_init();
// set cURL options
$curloptions = array(
CURLOPT_PUT => true, // set method to PUT
CURLOPT_RETURNTRANSFER => true, // return the transfer as a string
CURLOPT_VERBOSE => true, // output verbose information
CURLOPT_SSL_VERIFYHOST => false, // ignore self signed certificates
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERNAME => $config['uag']['user'], // set username
CURLOPT_PASSWORD => $config['uag']['pass'], // set password
CURLOPT_HTTPHEADER => array( // set headers
"Content-Type: application/json",
),
CURLOPT_POSTFIELDS => $jsondata // set data to post / put
);
curl_setopt_array($curl, $curloptions);
foreach($serverurilist as $uri) {
// set url
curl_setopt($curl, CURLOPT_URL, $uri);
// send the request and save response to $response
$response = curl_exec($curl);
// stop if fails
if(!$response) {
die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
}
var_dump($response);
}
// close curl resource to free up system resources
curl_close($curl);
What doesn't work? The payload / data doesn't get submitted. If I tcpdump the command line und php version without encryption, I can see, that the command line submits the data right after the Expect: 100-continue request and the HTTP/1.1 100 Continue response from the server. The php version doesn't do anything after the HTTP/1.1 100 Continue response and quits after reaching the timeout.
From documentation:
CURLOPT_PUT - true to HTTP PUT a file. The file to PUT must be set with CURLOPT_INFILE and CURLOPT_INFILESIZE.
and you are not using any file to provide content.
You should use CURLOPT_CUSTOMREQUEST => 'PUT'.
This is your same cUrl request exported from Postman:
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://blabla/blablabla',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_POSTFIELDS =>'<valid json data>',
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ='
],
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
You should use this CURLOPT_CUSTOMREQUEST=>'PUT'
Related
I am debugging why am I getting 400 response every time from the Laravel server.
When I am calling using Postman, everything works fine, but when I call from my curl script it returns 400 everytime.
My curl code looks like this:
$endpoint = "http://sup.l/api/iasku/IA00000001-My Beat-29999-H?";
$additional_headers = "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9zdXAubG9jYWxcL2FwaVwvbG9naW4iLCJpYXQiOjE2MDE2MjI2MDQsImV4cCI6MTYwMTcwOTAwNCwibmJmIjoxNjAxNjIyNjA0LCJqdGkiOiJITFAyUEhWeEdQU1J0NWFQIiwic3ViIjoxLCJwcnYiOiI4N2UwYWYxZWY5ZmQxNTgxMmZkZWM5NzE1M2ExNGUwYjA0NzU0NmFhIn0.3t15l573A_EHotUq6Ud3fcGegXZh1tGsMf3i9BlrVWU";
$headers = array_merge([
'Content-Type: application/json',
'Accept: application/json',
], $additional_headers );
$options = [
CURLOPT_URL => $endpoint,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => 1, // return web page
CURLOPT_HEADER => 0, // don't return headers
CURLOPT_FOLLOWLOCATION => 1, // follow redirects
CURLOPT_ENCODING => "", // handle all encodings
CURLOPT_USERAGENT => "myuser.agent", // who am i
CURLOPT_AUTOREFERER => 1, // set referer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
CURLOPT_TIMEOUT => 120, // timeout on response
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
CURLOPT_SSL_VERIFYPEER => 0, // Disabled SSL Cert checks,
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_HTTPHEADER => $headers,
];
if (count($body)) {
$options['CURLOPT_POSTFIELDS'] = json_encode($body);
}
$ch = curl_init();
curl_setopt_array( $ch, $options );
$content = curl_exec( $ch );
My curl command looks like this (works fine):
curl --request DELETE \
--url http://sup.l/api/iasku/IA00000001-My%20Beat-29999-H? \
--header 'authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9zdXAubG9jYWxcL2FwaVwvbG9naW4iLCJpYXQiOjE2MDE2MjI2MDQsImV4cCI6MTYwMTcwOTAwNCwibmJmIjoxNjAxNjIyNjA0LCJqdGkiOiJITFAyUEhWeEdQU1J0NWFQIiwic3ViIjoxLCJwcnYiOiI4N2UwYWYxZWY5ZmQxNTgxMmZkZWM5NzE1M2ExNGUwYjA0NzU0NmFhIn0.3t15l573A_EHotUq6Ud3fcGegXZh1tGsMf3i9BlrVWU'
Can anyone see what is the problem here? And how should I debug this?
The problem here was that my URL had spaces, so the server couldn't process it.
Once I added rawurlencode for this part of URL IA00000001-My Beat-29999-H? it started working as expected.
I am using PHP curl to do basic Auth that return a jwt token.
When I Request the token in shell using curl i get a token of length 381 .However when I do the request in my php code i only get a token of length 326 which is not complete which lead to other problems in my other php requests .
how can i make my php code give me the full length of my token that is 381 in my response and not just 326?
Update my cURL shell code is :
curl --location --request POST 'https://xxxx/xxxx/auth/login' \
--header 'Authorization: Basic XXXXX'
my curl php code :
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://xxxxx/xxxxx/auth/login",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => array( "Authorization: Basic xxxxxxx" ),
) );
$response = curl_exec($curl);
curl_close($curl); echo $response;
Thanks
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=
Here is my code:
// Build request URL
$url = 'https://connect.squareup.com/v2/locations/';
// Build and execute CURL request
$options = array(
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => false, // don't return headers
CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
CURLOPT_ENCODING => "", // handle compressed
CURLOPT_AUTOREFERER => true, // set referrer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // time-out on connect
CURLOPT_TIMEOUT => 120, // time-out on response
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Authorization: Bearer ' . $accessToken,
'Accept: application/json',
)
);
$ch = curl_init($url);
curl_setopt_array($ch, $options);
$content = curl_exec($ch);
curl_close($ch);
var_dump($content);
Here is what I get back:
string(158) "{"errors":[{"category":"INVALID_REQUEST_ERROR","code":"NOT_FOUND","detail":"API endpoint for URL path `/v2/locations/` and HTTP method `GET` is not found."}]}"
I am pounding my head on this one... I tried using the Square SDK but calling from it doesn't return a list of locations either.
I have created an application on the Square Developer Dashboard. $accessToken is set to the sandbox access token listed there.
You have added an extra / at the end of the url. You should instead use:
$url = 'https://connect.squareup.com/v2/locations';
Other than that your code works!
I'm new with the Dropbox API integrations, and I'm using the PHP cURL extension to make calls to the HTTP REST API, and when I try to make a request I receive the following string:
Error in call to API function "files/list_folder":
Bad HTTP "Content-Type" header:
"text/plain; boundary=----------------------------645eb1c4046b".
Expecting one of "application/json", "application/json; charset=utf-8",
"text/plain; charset=dropbox-cors-hack".
I'm sending this with code very similar to this:
$sUrl = "https://api.dropboxapi.com/2/files/list_folder";
$oCurl = curl_init($sUrl);
$aPostData = array('path' => '', 'recursive' => true, 'show_hidden' => true);
$sBearer = "MY_TOKEN";
$aRequestOptions = array(
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => array('Content-Type: text/plain',
'Authorization: Bearer ' . $sBearer),
CURLOPT_POSTFIELDS => $aPostData,
CURLOPT_RETURNTRANSFER => true);
curl_setopt_array($aRequestOptions);
$hExec = curl_exec($oCurl);
if ($hExec === false){
// Some error info in JSON format
} else {
var_dump($hExec);
}
As you have it, you're doing a multipart form upload, which isn't what the API expects.
There are a few things you need to do differently:
You should be sending up the parameters as JSON in the body.
You should set the Content-Type to application/json, accordingly.
There isn't a show_hidden parameter on /files/list_folder, but perhaps you meant to send include_deleted.
The curl_setopt_array method takes two parameters, the first of which should be the curl handle.
Here's an updated version of your code that works for me:
<?php
$sUrl = "https://api.dropboxapi.com/2/files/list_folder";
$oCurl = curl_init($sUrl);
$aPostData = array('path' => '', 'recursive' => true, 'include_deleted' => true);
$sBearer = "MY_TOKEN";
$aRequestOptions = array(
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => array('Content-Type: application/json',
'Authorization: Bearer ' . $sBearer),
CURLOPT_POSTFIELDS => json_encode($aPostData),
CURLOPT_RETURNTRANSFER => true);
curl_setopt_array($oCurl, $aRequestOptions);
$hExec = curl_exec($oCurl);
if ($hExec === false){
// Some error info in JSON format
} else {
var_dump($hExec);
}
?>