Skip to content

Commit

Permalink
Always return ETag when etagMethod is set to "hash". Closes #29
Browse files Browse the repository at this point in the history
  • Loading branch information
kanongil committed Oct 18, 2015
1 parent 01fcc7f commit 2937c90
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 164 deletions.
72 changes: 43 additions & 29 deletions lib/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,11 @@ internals.prepare = function (response, callback) {
response.header('content-disposition', response.source.settings.mode + '; filename=' + encodeURIComponent(fileName));
}

internals.addEtag(response, stat, function () {
internals.addEtag(response, stat, function (err) {

if (err) {
return callback(err);
}

return callback(response);
});
Expand Down Expand Up @@ -132,39 +136,49 @@ internals.marshal = function (response, next) {
internals.addHashedEtag = function (response, stat, callback) {

var etags = response.request.server.plugins.inert._etags;
if (etags) {
if (!etags) {
return callback();
}

// Use stat info for an LRU cache key.
// Use stat info for an LRU cache key.

var path = response.source.path;
var cachekey = [path, stat.ino, stat.size, stat.mtime.getTime()].join('-');
var path = response.source.path;
var cachekey = [path, stat.ino, stat.size, stat.mtime.getTime()].join('-');

// The etag must hash the file contents in order to be consistent across distributed deployments
// The etag hashes the file contents in order to be consistent across distributed deployments

var cachedEtag = etags.get(cachekey);
if (cachedEtag) {
response.etag(cachedEtag, { vary: true });
}
else {
var hash = Crypto.createHash('sha1');
var processed = 0;
response.on('peek', function (chunk) {

hash.update(chunk);
processed += chunk.length;
});

response.once('finish', function () {

if (processed === stat.size) {
var etag = hash.digest('hex');
etags.set(cachekey, etag);
}
});
}
var cachedEtag = etags.get(cachekey);
if (cachedEtag) {
response.etag(cachedEtag, { vary: true });
return callback();
}

return callback();
// Perform the hashing

var hash = Crypto.createHash('sha1');
hash.setEncoding('hex');

var fileStream = Fs.createReadStream(path, { fd: response.source.fd, autoClose: false });
fileStream.pipe(hash);

var done = function (err) {

if (err) {
return callback(Boom.wrap(err, null, 'Failed to hash file'));
}

var etag = hash.read();
etags.set(cachekey, etag);

response.etag(etag, { vary: true });

return callback();
};

done = Hoek.once(done);

fileStream.on('end', done);
fileStream.on('error', done);
};


Expand Down Expand Up @@ -236,7 +250,7 @@ internals.openStream = function (response, path, next) {

Hoek.assert(response.source.fd !== null, 'file descriptor must be set');

var options = { fd: response.source.fd };
var options = { fd: response.source.fd, start: 0 };

internals.addContentRange(response, function (err, range) {

Expand Down
Loading

0 comments on commit 2937c90

Please sign in to comment.