Skip to content
Create a gist now

Instantly share code, notes, and snippets.

@gabceb /uploaders.js secret

Embed URL


Subversion checkout URL

You can clone with
Download ZIP
Uploads using Node/Websockets with some simple md5 validation
var app = require('http').createServer(handler);
var io = require('').listen(app);
var url = require('url');
var static = require('node-static');
var knox = require('knox');
var uploadCredential = require('./uploader/upload_credential');
var multiparty = require('multiparty');
var Batch = require('batch')
var PORT = (process.argv[2] == 'production') ? 80 : 8080;
var fileServer = new(static.Server)('./public');
function handler(req, res){
console.log("Received request")
req.query = url.parse(req.url, true).query;
if (isUploadRequest(req)) {
createUploadHandler(isValidCredential, authorizedUpload, unauthorizedUpload)(req, res);
fileServer.serve(req, res);
var s3Client = knox.createClient({
secure: false,
bucket: 'my-s3-bucket'
function createSendSocketMessage(socketid){
return function(room, message){
sendSocketMessage(socketid, room, message);
function sendSocketMessage(socketid, room, message){
io.sockets.socket(socketid).emit(room, message);
function isValidCredential(req){
return uploadCredential.isValid(req.query.security_hash, unescape(req.query.path));
function isUploadRequest(req){
return req.url.match(/^\/upload\?socketid=.+&security_hash=.+&path=.+/)
&& req.method.toLowerCase() == 'post';
function createUploadHandler(credentialValidator, funcAuthorized, funcUnauthorized){
return function(req, res){
funcAuthorized(req, res);
} else {
funcUnauthorized(req, res);
function unauthorizedUpload(req, res){
createSendSocketMessage(req.query.socketid)('upload_error', 'invalid credential');
res.writeHead(401, {'Content-type': 'text/plain'});
res.end('invalid credential');
function authorizedUpload(req, res){
var form = new multiparty.Form();
var batch = new Batch();
var currentSendSocketMessage = createSendSocketMessage(req.query.socketid);
batch.push(function(cb) {
form.on('field', function(name, value) {
if (name === 'path') {
var destPath = unescape(value);
if (destPath[0] !== '/') destPath = '/' + destPath;
cb(null, destPath);
batch.push(function(cb) {
form.on('part', function(part) {
if (! part.filename) return;
cb(null, part);
batch.end(function(err, results) {
if (err) throw err;
form.removeListener('close', onEnd);
var destPath = results[0], part = results[1];
console.log("Pushing file to " + destPath + " " + part.byteCount + " bytes.");
headers = {'Content-Length': part.byteCount, 'x-amz-acl': 'public-read'};
var file = s3Client.putStream(part, destPath, headers, function(err, s3Response) {
if (err) throw err;
res.statusCode = s3Response.statusCode;
console.log("Response code: " + s3Response.statusCode);
currentSendSocketMessage('uploaded_file', {path: destPath});
file.on('progress', function(e){
currentSendSocketMessage('upload_percentage', e.percent);
form.on('close', onEnd);
function onEnd() {
currentSendSocketMessage('uploaded_file', {
path: "No file uploaded"});

Hey @gabceb,
I'm trying to emulate your example here. I have a similar use case and trying to upload a file to an S3 bucket. Whenever I upload a file, the execution just goes through the "authorizedUpload" function and never enters the batch.end() part. Whereas a debug that I've put at the end of the function is seen(line 97 of the gist that I've put).

Here is my example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.