Curl POST upload file request returns false - php

I'm trying to use the gfycat API to create a gfycat with a file upload through curl with php but it doesn't work and var_dump($response) gives me bool(false).
My Code:
$file_path = $target_dir.$newfilename;
$cFile = curl_file_create($file_path);
$data = array(
"file" => $cFile,
);
$target_url = "https://filedrop.gfycat.com";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: multipart/form-data"
));
$response = curl_exec($ch);
var_dump($response); // bool(false) here
curl_close($ch);
Help would be really appreciated. Thanks.

Btw I got it to work with this:
$file_path = "ABSOLUTE_FILE_PATH".$newfilename;
$cFile = curl_file_create(realpath($file_path));
$data = array(
"key" => $newfilename,
"file" => $cFile,
);
$target_url = "https://filedrop.gfycat.com";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: multipart/form-data"
));
$response = curl_exec($ch);
curl_close($ch);

when debugging curl code, it's often a good idea to enable CURLOPT_VERBOSE and check the stderr log. further more, if curl_exec reutrned bool(false), it means there was a problem with the transfer, and you can use the curl_error() function to get an error message. and lastly, don't set the header "Content-Type: multipart/form-data" manually, curl will set that header for you, and unlike you, curl won't make any typos in doing so, and worse, you risk overwriting/removing the boundary parameter of the header.
try
$file_path = $target_dir . $newfilename;
$cFile = curl_file_create ( $file_path );
$data = array (
"file" => $cFile
);
$target_url = "https://filedrop.gfycat.com";
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $target_url );
curl_setopt ( $ch, CURLOPT_CUSTOMREQUEST, "POST" );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $data );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
try {
$stderrh = tmpfile ();
curl_setopt_array ( $ch, array (
CURLOPT_VERBOSE => 1,
CURLOPT_STDERR => $stderrh
) );
$response = curl_exec ( $ch );
if ($response === false) {
throw new \RuntimeException ( "curl error " . curl_errno ( $ch ) . ": " . curl_error ( $ch ) . " - verbose log: " . file_get_contents ( stream_get_meta_data ( $stderrh ) ['uri'] ) ); // https://bugs.php.net/bug.php?id=76268
}
} finally{
curl_setopt_array ( $ch, array (
CURLOPT_VERBOSE => 0,
CURLOPT_STDERR => STDERR
) );
fclose ( $stderrh );
}
var_dump ( $response ); // bool(false) here
curl_close ( $ch );
now, if there is an error, it should give you a nice detailed log of what happened up to to the curl error, in the exception error log.

Related

PHP CURL BadRequest

I am attempting to send a print job through PrintNode. I keep getting met with the same error message:
code: BadRequest
message: Incorrect request body: (request body).content must be present
I am relatively new to CURL, here is my code:
$pdf_path = plugin_dir_url( __FILE__ ) . 'pdfs/Order8221.pdf';
$url = 'https://api.printnode.com/printjobs';
$data_array = array(
'printerId' => 70029019,
'title' => 'My test print',
'contentType' => 'pdf_uri',
'content' => $pdf_path,
'source' => 'api doc'
);
$data = json_encode($data_array);
echo'<br/>';
print_r($data);
echo '<br/>';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERPWD, 'API KEY*******' . ":" . '');
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_HTTPHEADER, 'Content-Type: application/json');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$resp = curl_exec($ch);
Any help would be greatly appreciated.
I replaced
$data = json_encode($data_array);
with :
$data = http_build_query($data_array);
and it worked.

PHP curl_exec stops execution of the rest of the script without error logs

I have a php script running with curl and reporting setup as such, but it stops executing on the line with the curl_exec() method, and there are no errors thrown:
$fields = array(
'auth' => array(
'cId' => 'DEADBEEF-8675309-8675309-123123-4321',
'sig' => 'Not really a signature',
'data' => array(
'field' => 'pat',
'value' => '12',
'id1' => 'lasagna',
'id2' => 'peperoni'
)
),
'item1' => 'QPFMgH1TnCTLrylGeNs8yzYVVXxUgR0RHwj9jNwgXJJEfxODdoOKDOJLv66CSU5XKRfu4KYtDJB5rAmngxNrRDFpWU69oHMTlZoHAewuy3ft',
'item2' => 'gMiGdw==',
'tokenList' => array(
"token", "list"
)
);
$postfields = json_encode($fields);
error_reporting(E_ALL);
ini_set('display_errors', true);
$curl = curl_init('http://localhost:8080/endpoint');
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postFields);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
//curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
//$result = curl_exec($curl);
echo "before curl_exec" . "\n\n";
$response = json_decode(curl_exec($curl));
echo "after curl_exec" . "\n\n";
print_r($response);
EDIT: forgot to include the line with json_encode for the $fields variable to pass to curl_setopt();
There are a couple of issues with your code:
you put the "post" data into $fields but then...
curl_setopt($curl, CURLOPT_POSTFIELDS, $postFields);
...you're passing $postFields to curl.
Assuming this is a typo, fixing with
curl_setopt($curl, CURLOPT_POSTFIELDS, $fields);
won't work.
If the parameter used for CURLOPT_POSTFIELDS is an array it must be an associative array where keys and values are strings (or values that can be casted/converted to strings).
In your case $fields is an array where some values are arrays. That won't work (and raises a warning "array to string conversion").
You set an header that specifies that the data sent with the request is in JSON format
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
If you want to send the data into $fields as JSON with a POST request you can do it this way:
$fields = array( /* ... */ );
$json_fields = json_encode( $fields );
$curl = curl_init( 'http://localhost:8080/endpoint' );
curl_setopt( $curl, CURLOPT_POST, true );
curl_setopt( $curl, CURLOPT_CUSTOMREQUEST, "POST" );
curl_setopt( $curl, CURLOPT_POSTFIELDS, $json_fields );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $curl, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json',
'Content-Length: ' . strlen($json_fields) ] );
curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true );
$response = curl_exec( $curl );
$response_data = json_decode( $response );
If still something needs to be fixed proceed with debugging by steps to isolate the problem:
// 1 - Check curl error
$errnum = curl_errno( $curl );
$errstr = curl_strerror( $errnum );
echo "Error: $errnum - $errstr\n";
// 2 - Check http status code of the response
$status = curl_getinfo( $curl, CURLINFO_HTTP_CODE );
echo "Status: $status\n";
// 3 - Inspect the response before coverting to JSON
echo "Response:\n";
var_export( $response );
echo "\n";

"Invalid Request" while trying to get eBay user Access Token. No specific error number given

This is the extremely vague response I'm getting, while trying to get a user access token:
{
"error":"invalid_request",
"error_description":"request is invalid",
"error_uri":null
}
Here is my code:
$headers = array (
"Authorization: ".sprintf(
'Basic %s',
base64_encode(sprintf('%s:%s', $client_id, $client_secret))
)." ",
'Content-Type:application/x-www-form-urlencoded'
);
$apiURL = "https://api.sandbox.ebay.com/identity/v1/oauth2/token";
$urlParams = array (
"grant_type" => "authorization_code",
"code" => $auth_code,
"redirect_uri" => "xxx-xxx-xxx-SBX-ccd-xxx"
);
$data_json = json_encode($urlParams);
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt ( $ch, CURLOPT_POST, 1 );
curl_setopt ( $ch, CURLOPT_HEADER, 1 );
curl_setopt($ch, CURLOPT_URL, $apiURL);
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $data_json );
$resp = curl_exec ( $ch );
curl_close ( $ch );
print_r ( $resp );
How can I debug this when it doesn't even hint at what's wrong with my request?
I've been through this page step-by-step:
https://developer.ebay.com/devzone/rest/ebay-rest/content/oauth-gen-user-token.html#Updating
It seems that you encode your body in Json while the authorization server expects body parameters in POST field format.
The headers should also contains key/value pairs but you are sending only a list of values
Could you please try with the following code:
$headers = array (
'Authorization' => sprintf('Basic %s',base64_encode(sprintf('%s:%s', $client_id, $client_secret))),
'Content-Type' => 'application/x-www-form-urlencoded'
);
$apiURL = "https://api.sandbox.ebay.com/identity/v1/oauth2/token";
$urlParams = array (
"grant_type" => "authorization_code",
"code" => $auth_code,
"redirect_uri" => "xxx-xxx-xxx-SBX-ccd-xxx"
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Should be removed on production
curl_setopt ( $ch, CURLOPT_POST, 1 );
curl_setopt ( $ch, CURLOPT_HEADER, 1 );
curl_setopt($ch, CURLOPT_URL, $apiURL);
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $urlParams );
$resp = curl_exec ( $ch );
curl_close ( $ch );
print_r ( $resp );
Authorization header should have a following format:
'Authorization' => sprintf('Basic <%s>',base64_encode(sprintf('%s:%s', $client_id, $client_secret)))

Google Firebase iOS push works in console but not in API

I'm using https://github.com/arnesson/cordova-plugin-firebase/ to receive Google Firebase messages on a ionic based app.
After set certificates, install plugin and setup Firebase account I was able to receive notifications (on both android and ios devices) sended through the Firebase Console.
But when I send through the Firebase API (https://firebase.google.com/docs/cloud-messaging/http-server-ref) only android devices receive the notification. I'm using the following code:
$data = Array
(
[to] => <token>
[notification] => Array
(
[title] => My Title
[text] => Notification test
[sound] => default
[vibrate] => 1
[badge] => 0
)
)
$jsonData = json_encode($data);
$ch = curl_init("https://fcm.googleapis.com/fcm/send");
$header = array(
'Content-Type: application/json',
"Authorization: key=".$gcmApiKey
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, true );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
$result = curl_exec($ch);
curl_close($ch);
echo $result;
No errors are returned:
{"multicast_id":904572753471539870406,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1477063422322568734%3d5c78243d5c7824"}]}
What can be wrong?
For iOS, try adding in parameter priority set to high and content_available set to true in your payload.
See the parameter details here.
try this code
function sendGCM($message, $id) {
$url = 'https://fcm.googleapis.com/fcm/send';
$fields = array (
'registration_ids' => array (
$id
),
'data' => array (
"message" => $message
)
);
$fields = json_encode ( $fields );
$headers = array (
'Authorization: key=' . "YOUR_KEY_HERE",
'Content-Type: application/json'
);
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $url );
curl_setopt ( $ch, CURLOPT_POST, true );
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $fields );
$result = curl_exec ( $ch );
echo $result;
curl_close ( $ch );
}
?>
also try it in curl terminal
curl -X POST --header "Authorization: key=<API_ACCESS_KEY>" --Header "Content-Type: application/json" https://fcm.googleapis.com/fcm/send -d "{\"to\":\"<YOUR_DEVICE_ID_TOKEN>\",\"notification\":{\"body\":\"Yellow\"},\"priority":10}"
a little late but with working example,
I'm using the code below for ios and android push, you are missing the priority and content_available fields
example :
$url = 'https://fcm.googleapis.com/fcm/send';
$fields = array(
'to' => $token,
'notification' => array('body' => $message , "sound" => "default"),
'data' => $message,
"sound"=> "default",
'priority' => "high" ,
'content_available' => false
);
$headers = array(
'Authorization:key = your-key',
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);

POST JSON to API and retrieve data with PHP

I'm trying to use this API and POST to it with the required parameters.
Using this code:
function postToService_php( $urlAbs, $data ) {
$dataJSON = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $urlAbs);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $dataJSON);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($dataJSON))
);
$resultJSON = curl_exec($ch);
return $resultJSON;
}
$postData = array(
'UserName' => '*username*',
'Password' => '*password*',
'Area' => 1
);
var_dump(postToService_php('http://e20prodwebapi.esmartapi.com/api/Authenticate', $postData));
This seems to give string(0) "" as a result, what am I doing wrong here?
this API https is required. I don't have account so can't test.
https://e20prodwebapi.esmartapi.com/api/Authenticate
Use this: Consider you have to use SSL for this site (HTTPS)
<?php
function postToService_php( $urlAbs, $data ) {
$dataJSON = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $urlAbs);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $dataJSON);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_HEADER, 1); //Remove this line if everything works okay.
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 20);
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($dataJSON))
);
$resultJSON = curl_exec($ch);
return $resultJSON;
}
$postData = array(
'UserName' => 'test',
'Password' => 'test',
'Area' => 1
);
var_dump(postToService_php('https://e20prodwebapi.esmartapi.com/api/Authenticate', $postData));
On a hunch I tried https and received the expected 401 response using this code
function postToService_php( $url, $data ) {
$ch = curl_init();
$data=json_encode( $data );
curl_setopt($ch, CURLOPT_URL, $url );
if( parse_url( $url,PHP_URL_SCHEME )=='https' ){
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 2 );
curl_setopt( $ch, CURLOPT_CAINFO, realpath( 'c:/wwwroot/cacert.pem' ) );
}
curl_setopt($ch, CURLOPT_POST, true );
curl_setopt($ch, CURLOPT_POSTFIELDS, $data );
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen( $data ))
);
$result = curl_exec( $ch );
$info=curl_getinfo( $ch );
curl_close( $ch );
return (object)array(
'result'=> $result,
'info' => $info
);
}
$url='https://e20prodwebapi.esmartapi.com/api/Authenticate';
$postData = array(
'UserName' => 'geronimo',
'Password' => 'passthedoobie',
'Area' => 1
);
print_r( postToService_php( $url, $postData ) );

Categories