diff --git a/src/backupformat/rsync.js b/src/backupformat/rsync.js index 6c7156f9b..b9cd7d546 100644 --- a/src/backupformat/rsync.js +++ b/src/backupformat/rsync.js @@ -19,6 +19,7 @@ const assert = require('assert'), debug = require('debug')('box:backupformat/rsync'), { EncryptStream } = require('../hush.js'), fs = require('fs'), + HashStream = require('../hash-stream.js'), hush = require('../hush.js'), path = require('path'), paths = require('../paths.js'), @@ -52,7 +53,7 @@ async function addFile(sourceFile, encryption, uploader, progressCallback) { progressCallback({ message: `Uploading ${sourceFile}: ${transferred}M@${speed}MBps` }); // 0M@0MBps looks wrong }); - const hash = crypto.createHash('sha256'); + const hash = new HashStream(); let pipeline = null; if (encryption) { diff --git a/src/backupformat/tgz.js b/src/backupformat/tgz.js index 6874e501e..734a735a2 100644 --- a/src/backupformat/tgz.js +++ b/src/backupformat/tgz.js @@ -8,6 +8,7 @@ const assert = require('assert'), debug = require('debug')('box:backupformat/tgz'), { DecryptStream, EncryptStream } = require('../hush.js'), fs = require('fs'), + HashStream = require('../hash-stream.js'), path = require('path'), ProgressStream = require('../progress-stream.js'), promiseRetry = require('../promise-retry.js'), @@ -141,7 +142,7 @@ async function tarPack(dataLayout, encryption, uploader, progressCallback) { const pack = tar.pack(); - const hash = crypto.createHash('sha256'); + const hash = new HashStream(); let pipeline = null; if (encryption) { diff --git a/src/hash-stream.js b/src/hash-stream.js new file mode 100644 index 000000000..95b52a653 --- /dev/null +++ b/src/hash-stream.js @@ -0,0 +1,39 @@ +'use strict'; + +const crypto = require('crypto'), + stream = require('stream'), + TransformStream = stream.Transform; + +class HashStream extends TransformStream { + #hasher; + #digest; + #size; + + constructor() { + super(); + this.#hasher = crypto.createHash('sha256'); + this.#digest = null; + this.#size = 0; + } + + digest() { + return this.#digest; + } + + size() { + return this.#size; + } + + _transform(chunk, encoding, callback) { + this.#hasher.update(chunk); + this.#size += chunk.length; + callback(null, chunk); + } + + _flush(callback) { + this.#digest = this.#hasher.digest('hex'); + callback(null); + } +} + +exports = module.exports = HashStream; \ No newline at end of file