Allowing File Uploads direct from Dropbox

It's been over 3 months since Dropbox announced the availability of 'Chooser', a simple way to allow users to upload files to your site direct from their Dropbox, but I've not seen it in use anywhere. That's a little dissapointing really, partially because it's incredibly simple to use and implement, but also because I was really hoping it might prompt some of Dropbox's competitors to create something similar.

It makes life a lot easier for your users (especially those who want to upload from a *cough iOS* device with file uploads disabled ) and the hassle of setting it up is minimal.

In this post, I'll be showing how to implement the Dropbox chooser into a simple PHP site

So, let's start by creating a simple upload form, allowing the user to use either the standard upload element, or the Dropbox chooser. Before we start, you'll need to create an API Key (one of my few bugbears about this to be honest)

<html>
<body>
<script type="text/javascript"
src="https://www.dropbox.com/static/api/1/dropbox.js" id="dropboxjs"
data-app-key="YOURKEY">
</script>

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

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

<!-- Now we implement the Dropbox bits -->
<input type="dropbox-chooser" id="db-chooser"
name="dropbox-selected-file" style="visibility: hidden;" data-link-type="direct" />
<div class="alert alert-info" id="dbchosen"></div>

<!-- Dropbox stuff finished, simple huh? -->
<input type="submit" value="Upload">

</form>
</body>
</html>

It's that simple. Admittedly, a little boring as all that will happen when the user selects a file is the Dropbox icon will get a Green tick on it, so let's add an event handler to display the file information

<script type="text/javascript">
document.getElementById("db-chooser").addEventListener("DbxChooserSuccess", function(e) {
document.getElementById('dbchosen').innerHTML = "You selected " + e.files[0].link;
document.getElementById('oldstyleupload').style.display = 'none';

},
false);
</script>

Now the user will get a little more feedback. It's up to the reader to explore a little more with this, let's move onto actually processing the upload.

In our markup above we're posting the data to upload.php, so we need to create that file. We're going to put the uploaded data into a directory called uploads (original huh?) 

 

<?php

function retrieve_dropbox_file(){
$tmpdir = '/tmp' $url = $_POST['dropbox-selected-file'];

// Retrieve the file
$ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,5);
$data = curl_exec($ch); curl_close($ch);

// Write the data to a temporary file $urlpath = parse_url($url); $fname = basename($urlpath['path']);

$tmpfile['name'] = $fname;
$tmpfile['tmp_name'] = $tmpdir . "/" . $fname; $fh = fopen ($tmpfile['tmp_name'],'w'); fwrite($fh,$data); fclose($fh);

// Return the data necessary for the final bit of the script to do it's job return $tmpfile; }

// For our purposes Dropbox files take priority. // There's no reason you can't allow both, though! if ($_POST['dropbox-selected-file']){ $file = retrieve_dropbox_file(); }else{ $file = $_FILES['oldstyleupload']; }
rename($file['tmp_name'],'./uploads/'.$file['name']); ?>

It's that simple! There are a few changes you need to make before putting into a production system, though most are things you should already have noticed are lacking!

  1. Limit requests to URL's starting in https://dl.dropbox.com -  you don't want your upload script being used in DDoS attacks do you?
  2. Add in a random form token so that requests can only come from your form (partially links to number 1, but also so people can't so easily fill your hard-drive with random rubbish).

 In those few easy steps, you've now made the following possible (or more easily so) so long as the user has the file in their Dropbox account.

  • Large file uploads by people on slow connections
  • File uploads by iOS users
  • Upload of a file from any of the users devices

I'd love to see some of Dropbox's competitors release something similar, imagine being able to upload a document straight from Google Drive, or even an ICAL file straight from Google Calendar...