several times during the last few months, i wanted to receive a large file, too big to send/receive it via email. therefor i created a workflow to even get such files using a server at uberspace, node.js and btsync.

as simple as one, two, three.

  1. the user initiates the file transfer through a simple html form
  2. once the file has been uploaded, the server moves it to a btsync folder.
  3. this folder is being synchronized with my mac, which pushes the downloaded file to my desktop.

prerequisites

this howto shows the steps, necessary to run it using an account at uberspace.

please make sure, node.js (see uberspace wiki) and btsync (see my guide to setup btsync on uberspace (german)) are properly installed on your server.

node.js and the html form

node.js logo

scripting your server

on your server create two new directories:
$ mkdir -p ~/uploadjs/receiving

inside ~/uploadjs lives the script itself, the subfolder receiving is used to store incoming files.

now open ~/uploadjs and create a new file named upload.js:
$ cd ~/uploadjs && nano upload.js

please copy & paste the following code, set YOURUSERNAMEand YOURPORT (to get help choosing your port, read this: https://wiki.uberspace.de/system:ports), then save it ([ctrl] + [O]utput):

var formidable = require('formidable'),
	http = require('http'),
	util = require('util'),
	fs = require('fs'),
	homedir = 'YOURUSERNAME',
	port = 'YOURPORT';

http.createServer(function(req, res) {
  if (req.url == '/upload' && req.method.toLowerCase() == 'post') {
	// parse a file upload
	var form = new formidable.IncomingForm();

	form.encoding = 'utf-8';
	form.multiples = 'md5';
	form.uploadDir = '/home/' + homedir + '/uploadjs/receiving';

	form.parse(req, function(err, fields, files) {
	  var tmp_path = files.upload.path;
	  var dest_path = '/home/'+homedir+'/BTSync/storage/uploadjs/' + files.upload.path.replace('/home/' + homedir + '/uploadjs/receiving/', '') + '_' + files.upload.name;
	  fs.rename(tmp_path, dest_path, function(err) {
		if ( err ) console.log('ERROR: ' + err);
	  });

	  res.writeHead(200, {'content-type': 'text/plain'});
	  res.end('received upload: ' + files.upload.name);
	});

	return;
  }

  // show a file upload form
  res.writeHead(200, {'content-type': 'text/html'});
  res.end(
	'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'+
	'<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">'+
	'<head>'+
	'<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />'+
	'</head><body>'+
	'<form action="/upload" enctype="multipart/form-data" method="post" />'+
	'<input type="file" name="upload" multiple="multiple" /><br />'+
	'<input type="submit" value="Upload" />'+
	'</form>'+
	'</body></html>'
  );
}).listen(port);

create a deamon

create a service directory, if it doesn't exist:
$ test -d ~/service || uberspace-setup-svscan

and create a service to run our script:
$ uberspace-setup-service uploadjs node ~/uploadjs/upload.js

make it accessible worldwide

let's create a subdomain (change to fit your needs) and create a new .htaccess file to bind it to your port (chosen above):

$ mkdir /var/www/virtual/YOURUSERNAME/sub.domain.tld
$ nano /var/www/virtual/YOURUSERNAME/sub.domain.tld/.htaccess

contents of .htaccess (remember to set your port correctly):

RewriteEngine on
RewriteRule (.*) http://localhost:YOURPORT/$1 [P]

i highly recommend to secure the access to this form, using .htaccess and .htpasswd (german documentation in uberspace wiki)

bittorrent sync setup

please create the folder ~/BTSync/storage/uploadjs/ and setup up syncing with your computer using btsync.

you might want to read section 'bittorrent sync' in this article: how to download videos to your computer from any device.

done.

if you point your preferred browser to https://sub.domain.tld/ you can upload large files, which will be synchronized with your computer. mac users might want to read this: os x: automatically move files using folder actions.

main picture by stocksnap, CC0 1.0 license