Skip to content

Instantly share code, notes, and snippets.

@dobesv
Created January 3, 2012 08:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dobesv/1554120 to your computer and use it in GitHub Desktop.
Save dobesv/1554120 to your computer and use it in GitHub Desktop.
Sample connect/express middleware to add a digest to all file uploads. Useful for change detection, that kind of thing. Also an example of calculating a hash (SHA1 or MD5) on a file.
var crypto = require('crypto'),
fs = require('fs');
/**
* Calculate the digest of a given file as a hex string.
*
* @param filename Name of the file to read
* @param {String} [algo='sha1'] Hash algorithm (e.g. 'md5' or 'sha1')
* @param {function(Exception,String) cb Callback which is invoked with (err,hash)
*/
function digestFile(filename, algo, cb) {
if(typeof(algo) === 'function') {
cb = algo;
}
if(typeof(algo) !== 'string') {
algo = 'sha1';
}
var hash = crypto.createHash(algo);
var s = fs.ReadStream(filename);
s.on('data', function(d) {
hash.update(d);
});
s.on('end', function() {
cb(null, hash.digest('hex'));
});
s.on('error', function(err) {
cb(err);
})
}
exports.digestFile = digestFile;
/**
* Return middleware that will add the given hash
* to all file uploads. Assumes file uploads are
* being processed by formidable or the connect body parser.
*
* @param {String} [algo='sha1'] Hash algorithm to use, e.g. 'md5' or 'sha1'
*/
exports.middleware = function digestFileUploadsMiddleware(algo) {
return function digestFileUploads(req, res, next) {
var keys = req.files && Object.keys(req.files);
if(keys && keys.length) {
var pending=0;
keys.forEach(function digestFileUpload(k) {
var f = req.files[k];
pending++;
digestFile(f.path, algo, function(err, digest) {
if(err === null) {
f[algo] = digest;
}
pending--;
if(pending === 0) {
next();
}
})
});
} else {
next();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment