Uploading .tmp file instead of desired file to server - php

I am working on uploading a file to box.net.
I am sending the file using Curl,
But the problem i am facing is it does not upload the file I selected, Instead it uploads some .tmp file.
following is my code:
<?php
$upload_url = 'Server-Url';
$tmpfile = $_FILES['new_file1']['tmp_name'];
$_POST['new_file1'] = '#'.$tmpfile;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $upload_url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $_POST);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>
<form action=""
enctype="multipart/form-data" accept-charset="utf-8" method="POST">
<input type="file" name="new_file1" />
<input type="text" name="share" value="1" />
<input type="submit" name="upload_files" value="Upload File" />
</form>
Am i doing some thing wrong?
Please can any one help me out to solve this problem.

tmp_name is supposed to contain a temporary name. The actual file name is in the name element. See the manual.
However, with the code you have, if you use the name element, you introduce a huge vulnerability into your code, as an attacker may be able to make your script upload local files from your server. Use move_uploaded_file() to prevent that.

As far as I've seen curl does not offer to choose one file yet send a different name for it during upload. Unless you want to craft the whole HTTP request yourself to allow you for this flexibility, you'll have to rename the file on disk to give it the right name. Renaming a file to an arbitrary user-provided name is always a giant security risk though. Below I'm creating a unique temporary directory and am double-checking that the file will be moved into that directory to avoid path injection attacks and to avoid overwriting other files. There may or may not be more attack vectors I'm not thinking about though!
do {
$tmpDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid('upload');
} while (file_exists($tmpDir));
$uploadFile = realpath($tmpDir . DIRECTORY_SEPARATOR . basename($_FILES['new_file1']['name']));
if (strpos($uploadFile, $tmpDir) !== 0) {
trigger_error('File path not within expected directory', E_USER_ERROR);
exit;
}
mkdir($tmpDir, 0600);
move_uploaded_file($_FILES['new_file1']['tmp_name'], $uploadFile);
...
curl_setopt($ch, CURLOPT_POSTFIELDS, array('file' => "#$uploadFile"));
...
unlink($uploadFile);
rmdir($tmpDir);

Related

php send file to remote server using cURL

I want to send file from local to remote server and after saving file to server I want to output the response. I am using cURL to send and upload file. It is working when I try it on local but not on remote server.
I use sftp protocol with public authentication key for connection.
what I need to change to send file to server.
Here is my code.
$target_url = 'https://example.com/accept.php';
$file_name_with_full_path = realpath('ss.zip');
$post = array('file' => new CurlFile($file_name_with_full_path, 'application/zip' /* MIME-Type */, 'ss.zip'));
$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=curl_exec ($ch);
curl_close ($ch);
echo $result;
If you want to upload images to an external server which is uploaded to your site by a client, you are at the right tutorial.
For this submission we will use 2 files :
form.php – The Page Where we will show the client the form. This file also sends the uploaded data to the external server.
handle.php – The Page on the external server which receives the uploaded data from form.php using cURL.
We won’t copy the uploaded file by the client to our server, instead we will directly send the file to the external server. For sending we will encrypt the file with base64.
OK. Lets’ Start. First, Let’s create the FORM page :
<form enctype="multipart/form-data" encoding='multipart/form-data' method='post' action="form.php">
<input name="uploadedfile" type="file" value="choose">
<input type="submit" value="Upload">
</form>
<?
if ( isset($_FILES['uploadedfile']) ) {
$filename = $_FILES['uploadedfile']['tmp_name'];
$handle = fopen($filename, "r");
$data = fread($handle, filesize($filename));
$POST_DATA = array(
'file' => base64_encode($data)
);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://extserver.com/handle.php');
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $POST_DATA);
$response = curl_exec($curl);
curl_close ($curl);
echo "<h2>File Uploaded</h2>";
}
?>
Now the code of the handle.php in external server where we sent the data using cURL :
$encoded_file = $_POST['file'];
$decoded_file = base64_decode($encoded_file);
/* Now you can copy the uploaded file to your server. */
file_put_contents('subins', $decoded_file);
The above code will receive the base64 encoded file and it will decode and put the image to its server folder. This might come in handy when you want to have your own user file storage system. This trick is used by ImgUr and other file hosting services like Google.

Upload images to Imgur with Curl PHP

<form action="php.php" method="post" enctype="multipart/form-data">
Send these files:<br />
<input name="img[]" type="file" multiple="multiple" /><br />
<input type="submit" value="Send files" />
</form>
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
foreach ($_FILES['img']['tmp_name'] as $index => $tmpName) {
if( !empty( $tmpName ) && is_uploaded_file( $tmpName ) )
{
$handle = fopen($tmpName, "r");
$data = fread($handle, filesize($tmpName));
$client_id = "d5f419ef9aedf16";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.imgur.com/3/image.json');
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Client-ID ' . $client_id));
curl_setopt($ch, CURLOPT_POSTFIELDS, array('image' => base64_encode($data)));
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_STDERR, fopen('php://stderr', 'w'));
$reply = curl_exec($ch);
$info = curl_getinfo($ch);
var_dump($info);
if(curl_errno($ch))
echo 'Curl error: '.curl_error($ch);
curl_close($ch);
$reply = json_decode($reply);
printf('<img height="180" src="%s" >', $reply->data->link);
}
}
?>
I made this page, works perfectly on localhost but when I run it from my server it does not work, problem is I have no output at all, not even the curl_getinfo or errors. Dont know how to debug this since I can't get any info out of it.
Thank you hans for the suggestions, you were right, it was not mandatory to use base64, not in V3 API, it was on the previous versions, not anymore. Now it's much faster. This is my final code
if(!empty($_FILES['img']['tmp_name'])){
foreach ($_FILES['img']['tmp_name'] as $index => $tmpName) {
if( !empty( $tmpName ) && is_uploaded_file( $tmpName ) )
{
if ($handle = fopen($tmpName, "rb")) {
$data = stream_get_contents($handle, filesize($tmpName));
$client_id = "d5f619ef9aedf16";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.imgur.com/3/image.json');
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Client-ID ' . $client_id));
curl_setopt($ch, CURLOPT_POSTFIELDS, array('image' => $data));
curl_setopt($ch, CURLOPT_VERBOSE, true);
$reply = curl_exec($ch);
if(curl_errno($ch))
echo 'Curl error: '.curl_error($ch);
curl_close($ch);
$reply = json_decode($reply);
$screens .= $reply->data->link . " ";
fclose($handle);
}
}
}
}
The reason why it was not uploading them images was upload_max_filesize and max_post_size, I've increased them and I had no problems.
you do several things wrong.
this code:
foreach ($_FILES['img']['tmp_name'] as $index => $tmpName) { will be executed even on GET requests, which contains no files, thus $_FILES['img'] does not exist, and you get an Undefined index: img error. furthermore, on GET requests, this undefined index bug returns NULL to foreach, and when you tell foreach() to loop a NULL, it gives you this error: Invalid argument supplied for foreach(). the fact that you haven't already caught up on this, proves that you're not checking the php error logs. this is the first thing you should do, when debugging a malfunctioning php script. - to fix both of these, wrap the foreach in if(!empty($_FILES['img']['tmp_name']){} - next, find your PHP error logs, and read those error reports. (usually you can find it in phpinfo() under error_log - or in case its emptystring, its your web servers' error log, eg for nginx with an empty php error_log php setting, its in nginx's error log (like /var/log/nginx/error.log )
next issue, $handle = fopen($tmpName, "r"); this will corrupt binary data (like images) on some systems (famously, windows), change it to rb for safely reading binary data (and image formats are binary)
next issue, you believe that fread() reads as many bytes as you request it to read, that is incorrect. fread will read UP TO as many bytes as requested, but can stop for many reasons before it has read the requested number of bytes. you'll either have to loop calling fread until it has read all the bytes, or better yet, use stream_get_contents, which will essentially do that fread() loop for you.
next issue, this line curl_setopt($ch, CURLOPT_STDERR, fopen('php://stderr', 'w')); is completely unnecessary, PHP's STDERR is libcurl's default STDERR anyway.
next issue, you don't fclose() $handle. this is ok for short running scripts (becuase the OS fclose() it for you when the script finishes), but the bigger your code grows, the longer the resource leak will be there, its a good programming habit to always close it, so do that.
next issue, i can't believe imgur actually wants a base64 encoded copy of the image, that is such a cpu & bandwidth & ram waste... the POST encoding they're using, multipart/form-data is fully binary safe, so there's no reason to base64 encode it... are you sure they want it base64 encoded? you AND them can save about 33% bandwidth by NOT using base64 encoding here.
given all the things you are doing wrong with the file operations, it'd be better to use the file_get_contents function - it reads the entire file, it opens the file in binary read mode (as opposed to your code, where you open it in TEXT mode, potentially corrupting the image as you read it), and it reads the entire file, not just the chunk of it that the first fread() call will read (which, if you're lucky, is the entire file, but if you're not lucky, is just the first chunk of it), and it does fclose() for you (which you forget to do)
Why dont you use imgur php sdk and simple implement it with below code:
require_once APPPATH."/third_party/imgur/vendor/autoload.php";
$pathToFile = '../path/to/file.jpg';
$imageData = [
'image' => $pathToFile,
'type' => 'file',
];
$client->api('image')->upload($imageData);

PHP cURL setup to send to remote host

I have a few elementary questions about cURL that I can't find answered in the cURL docs (probably because they are obvious to everyone else...). I have a file type input in a form that needs to send that file to a remote server. Does the cURL code go on the page with the form, or is the cURL on the page that the form sends you to, then it gets sent to the remote server?
Here is the form html:
<form action="send.php" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<br />
<input type="submit" name="submit" value="Submit" />
</form>
The cURL php I have so far which I don't even know if it's correct for what I'm trying to do, or if this goes on the same page or the send.php file the form goes to:
$ch = curl_init("http://remoteServer/upload_file.php");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CUROPT_POSTFIELDS, array('fileupload' => '#'.$_FILES['theFile'] ['tmp_name']));
echo curl_exec($ch);`
And on the remote server I have this file to receive it:
$folder = "files/";
$path = $folder . basename( $_FILES['file']['name']);
if(move_uploaded_file($_FILES['file']['tmp_name'], $path)) {
echo "The file ". basename( $_FILES['file']['name']). " has been uploaded";
} else{
echo "There was an error uploading the file, please try again!";
}
Is this even remotely close?
you don't need curl to upload a file from a browser, you can submit the form directly to the remote server to upload - just make sure the form submits to whatever file has that third block of code
Try this
$curlPost = array('fileupload' => '#'.$_FILES['theFile'] ['tmp_name']);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://remoteServer/upload_file.php');
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$data = curl_exec();
curl_close($ch);
Another Example
How to upload image file to remote server with PHP cURL
http://www.maheshchari.com/upload-image-file-to-remote-server-with-php-curl/

How to implement imgur api (image host) on a website?

I came across http://api.imgur.com and thought that would be a usefull tool to use on my website. I then noticed that StackOwerflow uses it too, so it must be good )))
Although I'm struggling when I try to implement it. I took a look at
http://api.imgur.com/examples the PHP section, but it didn't help me much.
What I'm interested in is includin imgur api on my website so users can upload their images. I would than need to store img url/path so I can display it on a website.
e.g. have a form that will allow users to upload photo, then store url/path of the uploaded image in a database (VARCHAR).
Has anyone had a success with this system and could help me understand how to implement it like StackOwerflow uses it (only store image url in database not post).
Code I tried:
<form enctype="multipart/form-data" method="post" action="upload_img.php">
Choose your file here:
<input name="uploaded_file" type="file"/>
<input type="submit" value="Upload It"/>
</form>
upload_img.php
<?
$filename = "image.jpg";
$handle = fopen($filename, "r");
$data = fread($handle, filesize($filename));
// $data is file data
$pvars = array('image' => base64_encode($data), 'key' => IMGUR_API_KEY);
$timeout = 30;
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://api.imgur.com/2/upload.xml');
curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $pvars);
$xml = curl_exec($curl);
curl_close ($curl);
?>
I see that you have copy and pasted the example from the imgur API site, which gives the example of a filename which is contained within $filename. You need to point this variable at the file that PHP has uploaded.
Modify the $filename part of your script:
$filename = $_FILES['uploaded_file']['tmp_name'];
Source: POST method file uploading

my php curl upload dosn't work, display nothing?

i'm trying to test my server, and to do that,
i make a robot to upload one file (in future, i'll make it repeatedly)...
but, the upload file did not send...
here the curl
<?php
$postdata = array();
$postdata ['fieldname'] = "#/home/egy/Downloads/BIO11_0201001D.DBF"; //fieldname should be same as file input box name
$post_url = 'form-handler.php'; //url to upload file
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $post_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
$response = curl_exec($ch);
echo $response;
?>
and this is the handler:
<?php
if(move_uploaded_file($_FILES['fieldname']['tmp_name'], "upload"))
{
echo "success";
}
?>
in my php, i set display_error = on and error_reporting = E_ALL
my DBF never send to server, but there is no error or warning....
am i doing wrong?
NB: Sorry for my english
This is likely becuase you need to use $_FILES['fieldname']['name'] to get what the name was in the file input box named fieldname
Did you make sure you had an enctype in your form. Mistake a lot of people make, including my self.
<form method="post" action="" enctype="multipart/form-data">
Assuming you are trying to upload a file local to the box the script is running from.. see this stackoverflow question

Categories