gabceb / uploaders.js secret
Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

Uploads using Node/Websockets with some simple md5 validation

View uploaders.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
var app = require('http').createServer(handler);
var io = require('socket.io').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;
 
app.listen(PORT);
 
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);
return;
}
fileServer.serve(req, res);
}
 
var s3Client = knox.createClient({
secure: false,
key: 'XXXXXXXXXXXXXX',
secret: 'XXXXXYYYYVVVVVSSSSSDDDDD/',
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){
if(credentialValidator(req)){
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);
 
s3Response.pipe(res);
currentSendSocketMessage('uploaded_file', {path: destPath});
});
 
file.on('progress', function(e){
currentSendSocketMessage('upload_percentage', e.percent);
});
});
 
form.on('close', onEnd);
form.parse(req);
 
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.
https://gist.github.com/hariprasadkulkarni/cc0275587ecfa656b429

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.