1'use strict' 2 3var Transform = require('stream').Transform 4var crypto = require('crypto') 5var fs = require('graceful-fs') 6 7exports.check = check 8exports.checkSync = checkSync 9exports.get = get 10exports.getSync = getSync 11exports.stream = stream 12 13function check(file, expected, options, cb) { 14 if (typeof options === 'function') { 15 cb = options 16 options = undefined 17 } 18 expected = expected.toLowerCase().trim() 19 get(file, options, function (er, actual) { 20 if (er) { 21 if (er.message) er.message += ' while getting shasum for ' + file 22 return cb(er) 23 } 24 if (actual === expected) return cb(null) 25 cb(new Error( 26 'shasum check failed for ' + file + '\n' 27 + 'Expected: ' + expected + '\n' 28 + 'Actual: ' + actual)) 29 }) 30} 31function checkSync(file, expected, options) { 32 expected = expected.toLowerCase().trim() 33 var actual 34 try { 35 actual = getSync(file, options) 36 } catch (er) { 37 if (er.message) er.message += ' while getting shasum for ' + file 38 throw er 39 } 40 if (actual !== expected) { 41 var ex = new Error( 42 'shasum check failed for ' + file + '\n' 43 + 'Expected: ' + expected + '\n' 44 + 'Actual: ' + actual) 45 throw ex 46 } 47} 48 49 50function get(file, options, cb) { 51 if (typeof options === 'function') { 52 cb = options 53 options = undefined 54 } 55 options = options || {} 56 var algorithm = options.algorithm || 'sha1' 57 var hash = crypto.createHash(algorithm) 58 var source = fs.createReadStream(file) 59 var errState = null 60 source 61 .on('error', function (er) { 62 if (errState) return 63 return cb(errState = er) 64 }) 65 .on('data', function (chunk) { 66 if (errState) return 67 hash.update(chunk) 68 }) 69 .on('end', function () { 70 if (errState) return 71 var actual = hash.digest("hex").toLowerCase().trim() 72 cb(null, actual) 73 }) 74} 75 76function getSync(file, options) { 77 options = options || {} 78 var algorithm = options.algorithm || 'sha1' 79 var hash = crypto.createHash(algorithm) 80 var source = fs.readFileSync(file) 81 hash.update(source) 82 return hash.digest("hex").toLowerCase().trim() 83} 84 85function stream(expected, options) { 86 expected = expected.toLowerCase().trim() 87 options = options || {} 88 var algorithm = options.algorithm || 'sha1' 89 var hash = crypto.createHash(algorithm) 90 91 var stream = new Transform() 92 stream._transform = function (chunk, encoding, callback) { 93 hash.update(chunk) 94 stream.push(chunk) 95 callback() 96 } 97 stream._flush = function (cb) { 98 var actual = hash.digest("hex").toLowerCase().trim() 99 if (actual === expected) return cb(null) 100 cb(new Error( 101 'shasum check failed for:\n' 102 + ' Expected: ' + expected + '\n' 103 + ' Actual: ' + actual)) 104 this.push(null) 105 } 106 return stream 107}