PHP - CURLFile display nothing - php

I'm using Codeigniter and trying to send a file to another server but when I use new CURLFile() to make a file, the screen is display nothing and the file isn't sent.
Here's my code :
Testing.php
public function sendFile(){
$ch = curl_init();
$cfile = new CURLFile(base_url().'assets/upload/RAD PAPER.doc');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, array('file' => $cfile, 'filename'=>'name'));
curl_setopt($ch, CURLOPT_URL, 'http://localhost/devel/api/receive');
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data'));
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_exec($ch);
curl_close($ch);
}
and in the other server :
Api.php
public function receive(){
$folder = base_url().'assets/';
$path = $folder . $_FILES['file']['name'];
if(move_uploaded_file($_FILES['file']['tmp_name'], $path)) {
echo "The file ". basename( $_FILES['file']['name']). " has been uploaded";
}
echo "smthg to print";
print_r($_FILES['file']);
}
It's looks like function receive is never be called. But when I change this line :
curl_setopt($ch, CURLOPT_POSTFIELDS, array('file' => $cfile, 'filename'=>'name'));
to :
curl_setopt($ch, CURLOPT_POSTFIELDS, array('file' => 'thisisstring', 'filename'=>'name'));
return me the message 'smthg to print' in Api.php but $_FILES['file'] is undefined because it's not a file. What's wrong with my code? Do I wrong in using CURLFile? I'd try curl_file_create() too.

Related

PHP POST API no file received

Our team is working on developing a web application for accessing a 3D printer remotely in PHP. We tried implementing the POST print_job part using the multipart/form-data but it doesn't work, which shows no file received. This API would check id and key. Here is the code. Any help is appreciated!
It's running on Apache 2.4.39, PHP 7.3.5, XAMPP Control Panel 3.2.2.
The details are:
<?php
function callAPI($method, $url, $data){
$curl = curl_init();
switch ($method){
case "POST":
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_POST, 1);
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
break;
case "PUT":
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
break;
default:
if ($data)
$url = sprintf("%s?%s", $url, http_build_query($data));
}
$username = "";
$password = "";
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
curl_setopt($curl, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 90);
curl_setopt($curl, CURLINFO_HEADER_OUT, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
// EXECUTE:
$result = curl_exec($curl);
if(!$result){die("Connection Failure");}
curl_close($curl);
return $result;
}
?>
<?php
include('api.php');
$_SESSION['ip'] = "";
$_SESSION['url'] = "http://".$_SESSION['ip']."/api/v1";
$target_dir = "../uploads/";
$target_file = $target_dir . basename($_FILES["file"]["name"]);
move_uploaded_file($_FILES["file"]["tmp_name"], $target_file);
$filedata = $_FILES["file"]["tmp_name"];
echo $target_file;
$data_array = array(
"jobname" => "file",
"file" => "new \CURLFile(realpath($filedata))"
);
$_SESSION['size'] = $_FILES['file']['size'];
//$make_call = callAPI('POST', $_SESSION['url']."/print_job", $data_array);
$response = callAPI('POST', $_SESSION['url']."/print_job", $data_array);
$_SESSION['print'] = $response;
header('location: ../index.php');
?>
Ps: If I want to upload the file which was got from front-end to the remote API, I may have to store it locally. Then I tried it as the following code. It works.
file_put_contents("E:/xyz/test.gcode",file_get_contents("../uploads/".$_FILES["file"]["name"]));
$filedata='E:/xyz/test.gcode';
if(!is_readable(realpath($filedata))){throw new \RuntimeException("upload file not readable!");}
$data_array = array(
'jobname' => 'file',
'file' => new \CURLFile($filedata)
);
first off, don't set the Content-Type:multipart/form-data header manually because you'll corrupt the boundary if you do. the full header looks something like:
Content-Type: multipart/form-data; boundary=------------------------777d48028c332f50
so remove this:
$headers = array("Content-Type:multipart/form-data");
and let curl set it for you. (curl will automatically set that header, with the correct boundary, when setting CURLOPT_POSTFIELDS to array.)
second, you're not sending an actual file here, you're just sending the literal string
new \CURLFile(realpath($filedata))
.. if you want to send the file pointed to by $filedata , do
$data_array = array(
"jobname" => "test",
"file" => new \CURLFile(realpath($filedata))
);
instead.

Upload file using Curl and receive them in Laravel method

I have been trying to upload file to using curl using laravel app end point.
Below code is on separate server.
$header = $this->getCurlHeader();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$this->url);
curl_setopt($ch, CURLOPT_HTTPHEADER,$header);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
// curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$cfile = new \CURLFile($this->filePath . $this->csvFile, 'text/csv','text.csv');
//print_r($cfile);exit;
$postData = array('csv' => $cfile);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
//curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$response = curl_exec($ch);
$hhtpCode = curl_getinfo($ch);
curl_close($ch);
//$this->dbg($hhtpCode);
$this->dbg(json_decode($response,1),1);
And receiving end in laravel app hosted on different server.
public function insert(Request $request, $feed=''){
//return response()->json(var_dump($request->all()));
//return response()->json("here in insert");
return response()->json($_FILES);
echo "here";
dd($_FILES);
}
It returns me empty response.
I am able to verify curl request using headers.
Any suggestion will be helpful.
Thanks.
You can try something like this on the source server instead:
$target_url = 'https://mywebsite.com'; // Write your URL here
$dir = '/var/www/html/storage/test.zip'; // full directory of the file
$cFile = curl_file_create($dir);
$post = array('file'=> $cFile); // Parameter to be sent
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=json_decode(curl_exec($ch));
curl_close ($ch);
From the destination server, print the request sent.
public function insert(Request $request){
dd($request->file);
}
please use curlfile method to upload files.
if(isset($_FILES) && !empty($_FILES['identity_doc']))
{
foreach($_FILES['identity_doc'] as $key => $file)
{
$data['document'.$i]= new CURLFile($_FILES['identity_doc']['tmp_name'][$i], $_FILES['identity_doc']['type'][$i],$_FILES['identity_doc']['name'][$i]);
}
}
if(isset($_POST['submit']))
{
$fileName=$_FILES['resume']['name'];
$type=$_FILES['resume']['type'];
$tempPathname=$_FILES['resume']['tmp_name'];
$handle = fopen($tempPathname, "r");
$POST_DATA = fread($handle, filesize($tempPathname));
$url="https://objectstorage.region-name.oraclecloud.com/p/par-id/n/namespace`enter code here`/b/bucket-name/o/images/".$fileName;
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS=>$POST_DATA ,
CURLOPT_HTTPHEADER => array(
'Content-Type: '.$type,
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($response) {
echo 'error';
} else {
echo $url;
}
}
?>
<form method="post" enctype="multipart/form-data">
<input type="file" name="resume">
<button type="submit" name="submit">submit</button>
</form>

curl upload file in foreach change my post value

I have derectory and start scan dir get only jpg files and put in array after start foreach
foreach(files as file) {
$cfile = new CURLFile('HERE FULL PATH TO FILE', $mime, $file);
$target_url = "https://xxxxx.com/api/handler.php";
$data = array('file' => $cfile, 'dir' => 'Derectory where need upload file if not exist i create in handler.php for example /var/www/xxx/test/');
$ch = curl_init($target_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // On dev server only!
$result = curl_exec($ch);
if ($result) {
curl_close($ch);
// do something
} else {
curl_close($ch);
// error
}
}
when I upload 1700 or more images
curl start change my
$_POST['dir']
for example in 1210-rd image that change my
$_POST['dir']
from
"/var/www/xxx/test/"
to
"/var/www/xxx/te/va/www/x"
like this
who know what the problem in this case Thanks.

Forward a binary file from form to remote server using curl

The following script works:
move_uploaded_file($_FILES['file']['tmp_name'], $filename);
echo exec('curl -X POST --data-binary #' . $filename . ' http://remote.api:8888/index/add');
Following doesn't:-
We will be disabling exec() soon and will be doing plenty of hardening so the above solution will not work.
I tried the following:
move_uploaded_file($_FILES['file']['tmp_name'], $filename);
$filetype = $_FILES['file']['type'];
$ch = curl_init('http://remote.api/index/add');
curl_setopt($ch, CURLOPT_PORT, 8888);
curl_setopt($ch, CURLOPT_POST, TRUE);
$cFile = curl_file_create($filename, $filetype, $_FILES['file']['name']); // php5.5+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, ['file' => $cFile]);
$x = curl_exec($ch);
curl_close($ch);
The server does not respond to this workaround.
What am I missing? Please note I am using php 5.5 thus curl_create_file
Thank you for all the help :)

Using PHP to upload an activity to Strava using API v3

I'm working on an application in which I'd like to be able to upload activities (GPX files) to Strava using it's API v3.
My application successfully handles the OAuth process - I'm able to request activities, etc, successfully.
However, when I try to upload an activity - it fails.
Here's the relevant sample of my code:
// $filename is the name of the GPX file
// $actual_file contains the full path
$actual_file = realpath($filename);
$url="https://www.strava.com/api/v3/uploads";
$postdata = "activity_type=ride&file=". "#" . $actual_file . ";filename=" . $filename . "&data_type=gpx";
$headers = array('Authorization: Bearer ' . $strava_access_token);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($ch, CURLOPT_POST, 3);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec ($ch);
Here's what I get in response:
{"message":"Bad Request", "errors":[{"resource":"Upload", "field":"file","code":"not a file"}]}
I then tried this:
// $filename is the name of the GPX file
// $actual_file contains the full path
$actual_file = realpath($filename);
$url="https://www.strava.com/api/v3/uploads";
$postfields = array(
"activity_type" => "ride",
"data_type" => "gpx",
"file" => "#" . $filename
);
$postdata = http_build_query($postfields);
$headers = array('Authorization: Bearer ' . $strava_access_token, "Content-Type: application/octet-stream");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($ch, CURLOPT_POST, count($postfields));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$fp = fopen($filename, 'r');
curl_setopt($ch, CURLOPT_INFILE, $fp);
$json = curl_exec ($ch);
$error = curl_error ($ch);
Here's what I get in response:
{"message":"Bad Request", "errors":[{"resource":"Upload", "field":"data","code":"empty"}]}
Clearly, I'm doing something wrong when trying to pass the GPX file.
Is it possible to provide a bit of sample PHP code to show how this should work?
For what it's worth - I'm fairly certain the GPX file is valid (it's actually a file I downloaded using Strava's export feature).
I hope that answering my own question less than one day after posting it isn't bad form. But I've got it working, so I may as well, just in case anyone else finds it useful...
// $filename is the name of the file
// $actual_file includes the filename and the full path to the file
// $strava_access_token contains the access token
$actual_file = realpath($filename);
$url="https://www.strava.com/api/v3/uploads";
$postfields = array(
"activity_type" => "ride",
"data_type" => "gpx",
"file" => '#' . $actual_file . ";type=application/xml"
);
$headers = array('Authorization: Bearer ' . $strava_access_token);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec ($ch);
Apparently, it's important not to include the CURLOPT_POST option.
Here is also a working Python example
import os
import requests
headers = {
'accept': 'application/json',
'authorization': 'Bearer <Token>',
}
dir = os.getcwd() + '/files/'
for filename in os.listdir(dir):
file = open(dir + filename, 'rb')
files = {
"file": (filename, file, 'application/gpx+xml'),
"data_type": (None, 'gpx'),
}
try:
response = requests.post('http://www.strava.com/api/v3/uploads',files=files, headers=headers)
print(filename)
print(response.text)
print(response.headers)
except requests.exceptions.RequestException as e: # This is the correct syntax
print(e)
sys.exit(1)

Categories