Skip to content

Commit

Permalink
Merge pull request #443 from stephenplusplus/spp--storage-handle-errors
Browse files Browse the repository at this point in the history
handle errors in read stream
  • Loading branch information
ryanseys committed Mar 11, 2015
2 parents f59f3e7 + 29ae1dd commit 812870d
Showing 1 changed file with 68 additions and 58 deletions.
126 changes: 68 additions & 58 deletions lib/storage/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,7 @@ File.prototype.createReadStream = function(options) {
} else {
this.getMetadata(function(err, metadata) {
if (err) {
throughStream.emit('error', err);
throughStream.end();
done(err);
return;
}

Expand Down Expand Up @@ -342,25 +341,21 @@ File.prototype.createReadStream = function(options) {
that.bucket.storage.makeAuthorizedRequest_(reqOpts, {
onAuthorized: function(err, authorizedReqOpts) {
if (err) {
throughStream.emit('error', err);
throughStream.end();
done(err);
return;
}

// For data integrity, hash the contents of the stream as we receive it
// from the server.
var localCrc32cHash;
var localCrcHash;
var localMd5Hash = crypto.createHash('md5');

request(authorizedReqOpts)
.on('error', function(err) {
throughStream.emit('error', err);
throughStream.end();
})
.on('error', done)

.on('data', function(chunk) {
if (crc32c) {
localCrc32cHash = crc.calculate(chunk, localCrc32cHash);
localCrcHash = crc.calculate(chunk, localCrcHash);
}

if (md5) {
Expand All @@ -369,61 +364,76 @@ File.prototype.createReadStream = function(options) {
})

.on('complete', function(res) {
if (rangeRequest) {
// Range requests can't receive data integrity checks.
throughStream.emit('complete', res);
throughStream.end();
return;
}

var failed = false;
var crcFail = true;
var md5Fail = true;

var hashes = {};
res.headers['x-goog-hash'].split(',').forEach(function(hash) {
var hashType = hash.split('=')[0];
hashes[hashType] = hash.substr(hash.indexOf('=') + 1);
util.handleResp(null, res, res.body, function(err) {
if (err) {
done(err);
return;
}

if (rangeRequest) {
// Range requests can't receive data integrity checks.
done(null, res);
return;
}

var failed = false;
var crcFail = true;
var md5Fail = true;

var hashes = {};
res.headers['x-goog-hash'].split(',').forEach(function(hash) {
var hashType = hash.split('=')[0];
hashes[hashType] = hash.substr(hash.indexOf('=') + 1);
});

var remoteMd5 = hashes.md5;
var remoteCrc = hashes.crc32c && hashes.crc32c.substr(4);

if (crc32c) {
crcFail =
new Buffer([localCrcHash]).toString('base64') !== remoteCrc;
failed = crcFail;
}

if (md5) {
md5Fail = localMd5Hash.digest('base64') !== remoteMd5;
failed = md5Fail;
}

if (validation === 'all') {
failed = remoteMd5 ? md5Fail : crcFail;
}

if (failed) {
var mismatchError = new Error([
'The downloaded data did not match the data from the server.',
'To be sure the content is the same, you should download the',
'file again.'
].join(' '));
mismatchError.code = 'CONTENT_DOWNLOAD_MISMATCH';

done(mismatchError);
} else {
done(null, res);
}
});

var remoteMd5 = hashes.md5;
var remoteCrc = hashes.crc32c && hashes.crc32c.substr(4);

if (crc32c) {
crcFail =
new Buffer([localCrc32cHash]).toString('base64') !== remoteCrc;
failed = crcFail;
}

if (md5) {
md5Fail = localMd5Hash.digest('base64') !== remoteMd5;
failed = md5Fail;
}

if (validation === 'all') {
failed = remoteMd5 ? md5Fail : crcFail;
}

if (failed) {
var error = new Error([
'The downloaded data did not match the data from the server.',
'To be sure the content is the same, you should download the',
'file again.'
].join(' '));
error.code = 'CONTENT_DOWNLOAD_MISMATCH';

throughStream.emit('error', error);
} else {
throughStream.emit('complete', res);
}

throughStream.end();
})

.pipe(throughStream);
}
});
}

// End the stream, first emitting an error or complete event.
function done(err, response) {
if (err) {
throughStream.emit('error', err);
} else {
throughStream.emit('complete', response);
}

throughStream.end();
}
};

/**
Expand Down

0 comments on commit 812870d

Please sign in to comment.