request.files is empty from php curl request - php

I am trying to convert this curl request to php.
curl -X POST -F "file=#test_img.jpg" "http://127.0.0.1:5000/FileUploading/UploadImage/"test_img.jpg"
This request is working correctly with the following flask-RESTful code
class UploadImage(Resource):
def post(self, fname):
file = request.files['file']
if file:
# From flask uploading tutorial
filename = secure_filename(file.filename)
file.save(os.path.join("Images/", filename))
return jsonify({"Path": "Images/" + filename})
else:
# return error
return {'False'}
However, the following php curl request returns error 400 as it seems the request.files parameter is empty.
$file_name = "test_img.jpg";
$post_data = array(
"file" => "#" . $file_name,
"type" => 'image/jpg'
);
$ch = curl_init();
debug_to_console(http_build_query($post_data));
$host = "http://127.0.0.1:5000";
$url = $host . "/FileUploading/UploadImage/" . $file_name;
debug_to_console($url);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$file_param = 'file=' . $file_name;
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
$headers = array();
$headers[] = "Content-Type: multipart/form-data";
debug_to_console($headers);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
debug_to_console('Error:' . curl_error($ch));
}
curl_close($ch);
I don't know what i am doing wrong in this php request

first off, don't try to upload files using the # method, it was deprecated in PHP 5.5, disabled-by-default in PHP 5.6, and completely removed in PHP 7.0.0, in modern PHP, use CURLFile to upload files. also in line 10 you don't urlencode $file_name, that's a bug. and in line 17 you're trying to encode it to application/x-www-form-urlencoded-format (via http_build_query), but the command you're trying to convert is using multipart/form-data-format, when you give CURLOPT_POSTFIELDS a string (as returned by http_build_query), curl will send it as application/x-www-form-urlencoded by default but to make curl send it in multipart/form-data-format (as you want), set CURLOPT_POSTFIELDS to an array, not a string, and curl will send it in multipart/form-data.

Related

CSV file upload in Php using curl

I am using Php as a frontend and Java as a backend. I have created an Post API for uploading file and using curl for api request.
I have hit my Api using Postman at that time it works fine but i am facing prodblem when i request api using Curl i don't eble to get what i am doing wrong.
Here is the curl requested data :-
$data2 = array(
'file' =>
'#' . $data1->file->tmp_name
. ';filename=' . $data1->file->name
. ';type=' . $data1->file->type
);
This is how i am sending curl request:-
$ch = curl_init();
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch,CURLOPT_URL,$this->url);
curl_setopt($ch, CURLOPT_HEADER, 1); //parveen
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); //parveen
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS,$data2);
$headers = array(
'Content-Type:'.$this->service->contentType,
'Launcher:'.$this->serverName,
'domain:'.$this->service->domain,
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$this->responseBody=curl_exec($ch);
Links where i find this solution:-
enter link description here
I search a lot to find the solution but nothing is worked for me so please help me .
Thanks
the way you're trying to upload the file hasn't been supported since the PHP5 days, and even in 5.5+ you'd need CURLOPT_SAFE_UPLOAD to upload with #. use CURLFile when uploading files, like
$data2 = array(
'file' => new CURLFile($data1->file->name,$data1->file->type,$data1->file->tmp_name)
);
also, don't use CURLOPT_CUSTOMREQUEST for POST requests, just use CURLOPT_POST. (this is also true for GET requests and CURLOPT_HTTPGET )
also, check the return value of curl_setopt, if there was a problem setting your option, it returns bool(false), in which case you should use curl_error() to extract the error message. use something like
function ecurl_setopt($ch,int $option,$value){
if(!curl_setopt($ch,$option,$value)){
throw new \RuntimeException('curl_setopt failed! '.curl_error($ch));
}
}
and protip, whenever you're debugging curl code, use CURLOPT_VERBOSE, it prints lots of useful debugging info

PHP : Trouble developing CURL request for file upload to API

I am having this problem from last few days to develop a CURL request in php to post file data to an API.
Here is the CURL request
$ curl --request POST \
--url 'UPLOAD_URL' \
--upload-file 'PATH_TO_FILE' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
for PATH_TO_FILE I have tried each and every method published over the web and stackoverflow too.
here is my PHP code
<?php
header('Content-Type: application/json');
$sheader = array('Authorization: Bearer '.$_SESSION['access_token']);
$filename = $_FILES['upload-file']['name'];
$filedata = $_FILES['upload-file']['tmp_name'];
$filesize = $_FILES['upload-file']['size'];
$filetype = $_FILES['upload-file']['type'];
if($filename != '')
{
$ch = curl_init();
$cFile = new CURLFile(realpath($filename), $filetype, 'harish.jpg');
//$cFile = '#'. realpath($filename);
$data = array('upload-file' => $cFile);
curl_setopt($ch, CURLOPT_POSTFIELDS, $cFile);
//curl_setopt($ch, CURLOPT_POSTFIELDS, realpath($filename));
curl_setopt($ch, CURLOPT_URL, $_POST['upload_url']);
curl_setopt($ch, CURLOPT_HTTPHEADER, $sheader);
curl_exec($ch);
echo json_encode($ch);
//echo json_encode(array('filename'=>$filename, 'temp_path'=>$filedata, 'basepath'=>realpath($filename)));
} else {
echo 'There is no file selected';
}
Mostly the solution i have found on the web are these two mentioned below
Method 1 (for php < 5.5)
'#'.$filepath
Method 2 (for php > 5.5)
CURLFile($filename, $filetype, 'somefile.jpg');
or
curl_file_create($filedata, 'image/jpeg', $filename);
None of the above worked for me. I have use realpath($filename) too inside CURLFile to fetch absolute path of the file, but sadly that also not worked.
I admit that CURLFile documentation is slightly ambiguous but the first constructor argument, $name, is in fact the physical path to the actual file you want to send, not the "friendly" name (which goes in the optional third argument, $postname). You should note there's something wrong since you never tell Curl about $_FILES['upload-file']['tmp_name']—it has no way to know what file you want to send.
So:
$filename = $_FILES['upload-file']['name'];
$filedata = $_FILES['upload-file']['tmp_name'];
$filesize = $_FILES['upload-file']['size'];
$filetype = $_FILES['upload-file']['type'];
$cFile = new CURLFile($filedata, $filetype, 'harish.jpg')
You aren't being notified about this because you're skipping error checking. You don't check the return value of any function, neither call curl_error() anywhere in your code.
One more error you have is that you pass the CURLFile instance this way:
curl_setopt($ch, CURLOPT_POSTFIELDS, $cFile);
Correct syntax should be like:
curl_setopt($ch, CURLOPT_POSTFIELDS, ['give_a_nice_post_name_here' => $cFile]);

How to use an array in an API using curl

I am trying to access the cdnify API to purge cache for an individual file ( https://cdnify.com/learn/api#purgecache )
This is my current code
$cdn_api_user = env('CDNIFY_API');
$cdn_api_password = env('CDNIFY_API_PASS');
$cdn_api_resource = env('CDNIFY_API_RESOURCE');
$cdnifyapicacheurl = 'https://' . $cdn_api_user . ':' . $cdn_api_password . '#' . 'cdnify.com/api/v1/resources/' . $cdn_api_resource . '/cache';
return print $cdnifyapicacheurl;
$fields = array(
'files' => $storageFilename
);
$fields_string = http_build_query($fields);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $cdnifyapicacheurl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
//unless you have installed root CAs you can't verify the remote server's certificate. Disable checking if this is suitable for your application
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//perform the HTTP DELETE
$result = curl_exec($ch);
//close connection
curl_close($ch);
the env variables at the top call in my api key, password, and resource for the url. I have verified I am logging in via that url.
When I debug through my code i get an error on
$fields = array(
'files' => $storageFilename
);
which is Array to string conversion.
The $storageFilename variable returns
$storageFilename = "/" . $directoryname . "/" . $asset->name;
which is the filename required for the API call of DELETE.
I can't get passed that $fields array. The other stuff below it may or may not run properly. I am just stuck on how to write this part out.
CURLOPT_POST is just there to indicate if some post data should be included in the HTTP request, so its value should a boolean (true or false).
If your array $fields represents the data to be posted, you need to use http_build_query() to assign them to CURLOPT_POSTFIELDS:
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields));
There is a return in your code that stops the code the curl code is not getting executed remove it or comment it using // and try again and CURLOPT_POST value is boolean true or false that indicates if you want to use post method or not, your CURL code is really messed up you want to use http delete method or post method ?? You can only use one method, please learn how to use php cURL first http://php.net/manual/en/book.curl.php

How to post files using cURL

I am using cURL for the first time. I have to send one image file and one audio file posted by the user.
My cURL code is working, but instead of an image file and an audio file my code is sending a .tmp file.
I googled it, but in every example I found they have used realpath of file directly.
I tried to find real path of the file, but I didn't find any solution.
Here is my code block in which I am collecting all data in an array to pass it to cURL:
$name = $_POST['name'];
$image = $_POST['image']['name'];
$imagetmp = $_POST['image']['tmp_name'];
$imagesize = $_POST['image']['size'];
$imagepath = '#'.$imagetmp;
$audio = $_POST['audio']['name'];
$audiotmp = $_POST['audio']['tmp_name'];
$audiosize = $_POST['audio']['size'];
$audiopath = '#'.$audiotmp;
$data = array("name" => $name, "image"=> $imagepath, "audio" => $audiopath); //array to sned data using cURL
//my cURL code to post data
Where am I doing wrong? How to send files using cURL?
This is what I used to post file data:
$filedata = file_get_contents('file_location/filename.jpg');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $filedata);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/octet-stream'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$return = curl_exec($ch);
curl_close($ch);
You can use file=#path with curl
curl -kiSs -X POST https://<domain>/path/to/api/files/ \
-F "param1=param2" \
-F "file=#/path/to/test.xlsx" \
-H "Authorization":"bearer eyJhbGciOiJIUzI1NiIsIn"
File successfully uploaded (test.xlsx!)

Construct a PHP POST request with binary data

I'm trying to construct a PHP POST request that includes some binary data, following on from a previous StackOverflow question. The data is being submitted to this API call: http://www.cyclestreets.net/api/#addphoto
This is my PHP code:
$file = $_FILES['mediaupload'];
$file_field="#$file[tmp_name]";
$fields = array(
'mediaupload'=>$file_field,
'username'=>urlencode($_POST["username"]),
'password'=>urlencode($_POST["password"]),
'latitude'=>urlencode($_POST["latitude"]),
'longitude'=>urlencode($_POST["longitude"]),
'datetime'=>urlencode($_POST["datetime"]),
'category'=>urlencode($_POST["category"]),
'metacategory'=>urlencode($_POST["metacategory"]),
'caption'=>urlencode($_POST["description"])
);
$fields_string = http_build_query($fields);
echo 'FIELDS STRING: ' . $fields_string;
$url = 'https://www.cyclestreets.net/api/addphoto.json?key=$key';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec ($ch);
This is what my PHP file outputs:
FIELDS STRING: mediaupload=%40%2Fprivate%2Fvar%2Ftmp%2FphpHjfkRP&username=testing&password=testing&latitude=auto&longitude=auto&datetime=auto&category=cycleparking&metacategory=good&caption=
API RESPONSE: {"request":{"datetime":"1309886656"},"error":{"code":"unknown","message":"The photo was received successfully, but an error occurred while processing it."},"result":{}}
I believe this means that everything else about the request is OK, apart from the format of the binary data. Can anyone tell me what I am doing wrong?
CURL can accept a raw array of key=>value pairs for POST fields. There's no need to do all that urlencode() and http_build_query() stuff. Most likely the # in the array is being mangled into %40, so CURL doesn't see it as a file upload attempt.
$fields = array(
'mediaupload'=>$file_field,
'username'=> $_POST["username"),
etc...
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields);
The http_build_query function generates a URL encoded query string which means that the "#file.ext" is URL encoded in the output as a string and cURL doesn't know that you're trying to upload a file.
My advice would be not to include the file to upload in the http_build_query call and included manually in the CURLOPT_POSTFIELDS.
$file = $_FILES['mediaupload'];
$file_field="#$file[tmp_name]";
$fields = array(
'username'=>urlencode($_POST["username"]),
'password'=>urlencode($_POST["password"]),
'latitude'=>urlencode($_POST["latitude"]),
'longitude'=>urlencode($_POST["longitude"]),
'datetime'=>urlencode($_POST["datetime"]),
'category'=>urlencode($_POST["category"]),
'metacategory'=>urlencode($_POST["metacategory"]),
'caption'=>urlencode($_POST["description"])
);
$fields_string = http_build_query($fields);
echo 'FIELDS STRING: ' . $fields_string;
$url = 'https://www.cyclestreets.net/api/addphoto.json?key=$key';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS, 'mediaupload=' . $file_field . '&' . $fields_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec ($ch);

Categories