One day during class, I’ve been asked by the professor to send to the other students a few documents consisting in a couple of PDFs and DOCXs. The overall dimension of the files exceeded 25MB, so emailing them wasn’t an option. I’d deleted my Dropbox account a few days ago, so I thought about putting them on Mega - while I was doing this I realized that the process was somehow long and cumbersome for what I needed:
- Open the Mega website
- Wait for it to load the locally installed extension
- Login to it
- Upload my files
- Get a sharing link
- Get a sharing key
- Forward the links & the keys to my classmates via IM or Email.
I decided that I didn’t like this method, and begun searching for alternatives. A quick throwaway service that I found was TinyUpload; it was comfy to use on desktop, but a real pain to use from mobile.
I then decided it was time to roll my own storage engine, fully customized and tailored to my needs, to solve this problem once for all.
Stack & Code
As of all my latest projects, I quickly yeoman-ized a Node.JS template and removed all the bells and whistles that I didn’t need.
I started to build a modular engine centered on easiness of use and platform compatibility, giving particular attention to the API aspect of it. One of my main concerns was making it suitable for a CLI interface, so that I could store files without ever leaving my terminal if needed - something that I thought would have been handy in the future especially for sharing code snippets.
After having fiddled around for some time with the file upload procedure - that proved itself to be a little more tricky than what I was expecting - I had my first working prototype: it was a simple POST upload endpoint backed by the popular Express framework, that made use of the multer middleware to handle big files and multipart-encoded uploads; GETting another API endpoint with a filename in the query would let you download it. As simple as it gets.
You can see how it looked like by browsing in the initial commits of Dumpster’s GitHub repo.
The substantial code bits follows, as one of my first rough proofs-of-concept:
var multer = require('multer');
Worried by the misuse the lack of authentication could have led to, I pondered what my auth options were beside “standard” usernames and password. I wanted Dumpster to be a dead-simple service, and I remembered about the Yubikey I had recently bought. “Perfect timing.” - I thought.
I forked Adam Baldwin’s Yubikey library and adapted it a little to suit my needs more comfortably, using Yubico’s API to validate my uploads. I included basic support for user differentiation in case in the future I had to give access to other people using different OTP tokens.
var yubikey = require('./yubikey.js'); // https://github.com/evilpacket/node-yubikey
Fast-forward to the current status
All this crappy code has evolved nicely in time, while I kept adding features to the project and making it an overall decent and more efficient platform - as you can see from the latest releases of Dumpster. Eventually I even packaged it into a Docker container and published it to the Hub.
I’ve made the authentication better and simpler, with support for multiple users and tokens. I’ve added automatic deletion of stored files after a given time, with a persistency layer (implemented via LevelDB) to avoid mess when restarting the server. I threw checksums in the mix, using HTTP headers to tell the client if the file the server got actually matched by the bit the one that was intended to be uploaded.
At some later stage I’ve also added a WebUI when I grew tired of using this terminal client I wrote:
A listing of the almost-complete stack used can be viewed at StackShare, also embedded below here.
As of today Dumpster is still happily running on a VPS, lending me a hand whenever I need to quickly share some files - be it from the terminal of from a web browser.
All in all it might not be the best software I’ve ever written, but I’ve had a lot of fun during the development process and learned cool new tricks; but the most important thing, however, is that I built something that I actually use and improve on a daily basis, and not the umpteenth proof-of-concept to be forgotten in a few weeks. I highly value this, as I think of it as an important corner stone in a developer’s growth.
Learn more about Dumpster by taking a look at its GitHub repository, at its online demo, or at its Codacy code quality overview.