Wednesday, November 4, 2015

How To Upload Image To Remote Server With cURL And PHP?

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.

cURL can do just about anything that a normal web browser can do including send a file via a post request.

CurlFile should be used to upload files with CURLOPT_POSTFIELDS. The curl API will be modified to look for objects of type CurlFile. The file given to CurlFile will not be opened/read until curl_setopt() call.

Alternative 1: Send a file with php/cURL via POST using absolute file uploaded path
$file_name_with_full_path = realpath('./upload/example.png');
 
$curl_handle = curl_init("https://example.com");
 
curl_setopt($curl_handle, CURLOPT_POST, 1);
$args['file'] = new CurlFile($file_name_with_full_path, 'image/png');
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $args); 
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);

 
//execute the API Call
$returned_data = curl_exec($curl_handle);
curl_close ($curl_handle);

echo $returned_data;


Alternative 2: Send a file with php/cURL via POST using form file field: Without CurlFile file uploading function
//index.php
<?php
if(isset($_POST['check_submit']))
{ 
    $tmpfile = $_FILES['assets']['tmp_name'];
    $filename = basename($_FILES['assets']['name']); 
    $filetype = $_FILES['assets']['type']; 
    
/* 
As the @ format is now deprecated. Use curl_file_create function instead as below
       $POST_DATA = array(
   'file' => '@'.$tmpfile.';filename='.$filename
  );
*/

    $POST_DATA = array(
   'file' => curl_file_create($tmpfile, $filetype, $filename)
  );

    // Connecting to external api via cURL
    $curl_handle = curl_init("https://example.com");  
    curl_setopt($curl_handle, CURLOPT_POST, 1);
    curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $POST_DATA); 
    curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
   
    //execute the API Call
    $returned_data = curl_exec($curl_handle);
    curl_close ($curl_handle);
 
    echo $returned_data;
}
?>


<form method="POST" action="" enctype="multipart/form-data">

<p>Select a file to upload : </p>

<input type="file" name="assets">

<input type="submit" name="check_submit"/>

</form>

This API is both inconvenient and insecure, it is impossible to send data starting with '@' to the POST, and any user data that is being re-sent via cURL need to be sanitized so that the data value does not start with @. In general, in-bound signalling usually vulnerable to all sorts of injections and better not done in this way.

Instead of using the above method, the following (Alternative 3) should be used to upload files with CURLOPT_POSTFIELDS:

Alternative 3: Send a file with php/cURL via POST using form file field: Recommended
Screenshot:
//index.php
<?php
if(isset($_POST['check_submit']))
{ 
    $tmpfile = $_FILES['assets']['tmp_name'];
    $filename = basename($_FILES['assets']['name']); 
    $filetype = $_FILES['assets']['type']; 

    // Connecting to external api via cURL
    $curl_handle = curl_init("https://example.com");  
    curl_setopt($curl_handle, CURLOPT_POST, 1);
    $args['file'] = new CurlFile($tmpfile, $filetype, $filename);
    curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $args); 
    curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
   
    //execute the API Call
    $returned_data = curl_exec($curl_handle);
    curl_close ($curl_handle);
 
    echo $returned_data;
}
?>

<form method="POST" action="" enctype="multipart/form-data">

<p>Select a file to upload : </p>

<input type="file" name="assets">

<input type="submit" name="check_submit"/>

</form>
The important function to handle file post via curl is CurlFile function. The syntax of CurlFile function is shown below:
/**
* @param string $name File name
* @param string $mimetype Mime type, optional
* @param string $postfilename Post filename, defaults to actual filename
*/
$args['file'] = new CurlFile($name, $mimetype = '', $postfilename = '');

Ref: https://wiki.php.net/rfc/curl-file-upload
http://php.net/manual/en/class.curlfile.php
http://stackoverflow.com/a/29122849

2 comments:

  1. For this example we use three files

    uploader.php -that receives the files on to the remote server.
    handler.php -is used to web based client to upload the file.
    curl_handler.php -PHP cURL uploading client to upload file.

    ReplyDelete