Skip to content

Commit

Permalink
Update internals to use async / await
Browse files Browse the repository at this point in the history
  • Loading branch information
kanongil committed Sep 19, 2017
1 parent 43127f6 commit c07e967
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 207 deletions.
17 changes: 0 additions & 17 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
language: node_js

node_js:
- "4"
- "6"
- "8"
- "node"

Expand All @@ -11,21 +9,6 @@ sudo: false
env:
- HAPI_VERSION=""

matrix:
include:
- node_js: "4"
env: HAPI_VERSION="@13"
- node_js: "4"
env: HAPI_VERSION="@14"
- node_js: "4"
env: HAPI_VERSION="@15"
- node_js: "6"
env: HAPI_VERSION="@13"
- node_js: "6"
env: HAPI_VERSION="@14"
- node_js: "6"
env: HAPI_VERSION="@15"

install:
- npm install
- npm install hapi$HAPI_VERSION
3 changes: 1 addition & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ init:
# Test against these versions of Node.js.
environment:
matrix:
- nodejs_version: "4"
- nodejs_version: "6"
- nodejs_version: "8"

# Install scripts. (runs after repo cloning)
install:
Expand Down
84 changes: 42 additions & 42 deletions lib/directory.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,23 +99,23 @@ exports.handler = function (route, options) {
etagMethod: settings.etagMethod
};

Items.serial(paths, (baseDir, nextPath) => {
Items.serial(paths, async (baseDir, nextPath) => {

fileOptions.confine = baseDir;

let path = selection || '';

File.load(path, request, fileOptions, (response) => {
try {
const response = await File.load(path, request, fileOptions);

// File loaded successfully

if (!response.isBoom) {
return reply(response);
}
return reply(response);
}
catch (err) {

// Not found

const err = response;
if (err.output.statusCode === 404) {
if (!settings.defaultExtension) {
return nextPath();
Expand All @@ -125,14 +125,13 @@ exports.handler = function (route, options) {
path = path.slice(0, -1);
}

return File.load(path + '.' + settings.defaultExtension, request, fileOptions, (extResponse) => {

if (!extResponse.isBoom) {
return reply(extResponse);
}

try {
const extResponse = await File.load(path + '.' + settings.defaultExtension, request, fileOptions);
return reply(extResponse);
}
catch (err) {
return nextPath();
});
}
}

// Propagate non-directory errors
Expand All @@ -156,28 +155,28 @@ exports.handler = function (route, options) {
return reply.redirect(resource + '/');
}

Items.serial(indexNames, (indexName, nextIndex) => {
Items.serial(indexNames, async (indexName, nextIndex) => {

const indexFile = Path.join(path, indexName);
File.load(indexFile, request, fileOptions, (indexResponse) => {
try {
const indexResponse = await File.load(indexFile, request, fileOptions);

// File loaded successfully

if (!indexResponse.isBoom) {
return reply(indexResponse);
}
return reply(indexResponse);
}
catch (err) {

// Directory

const err = indexResponse;
if (err.output.statusCode !== 404) {
return reply(Boom.badImplementation(indexName + ' is a directory'));
}

// Not found, try the next one

return nextIndex();
});
}
},
(/* err */) => {

Expand All @@ -189,7 +188,7 @@ exports.handler = function (route, options) {

return internals.generateListing(Path.join(baseDir, path), resource, selection, hasTrailingSlash, settings, request, reply);
});
});
}
},
(/* err */) => {

Expand All @@ -201,35 +200,36 @@ exports.handler = function (route, options) {
};


internals.generateListing = function (path, resource, selection, hasTrailingSlash, settings, request, reply) {
internals.generateListing = async function (path, resource, selection, hasTrailingSlash, settings, request, reply) {

Fs.readdir(path, (err, files) => {
let files;
try {
files = await Fs.readdir(path);
}
catch (err) {
return reply(Boom.internal('Error accessing directory', err));
}

if (err) {
return reply(Boom.internal('Error accessing directory', err));
}
resource = decodeURIComponent(resource);
const display = Hoek.escapeHtml(resource);
let html = '<html><head><title>' + display + '</title></head><body><h1>Directory: ' + display + '</h1><ul>';

resource = decodeURIComponent(resource);
const display = Hoek.escapeHtml(resource);
let html = '<html><head><title>' + display + '</title></head><body><h1>Directory: ' + display + '</h1><ul>';
if (selection) {
const parent = resource.substring(0, resource.lastIndexOf('/', resource.length - (hasTrailingSlash ? 2 : 1))) + '/';
html = html + '<li><a href="' + internals.pathEncode(parent) + '">Parent Directory</a></li>';
}

if (selection) {
const parent = resource.substring(0, resource.lastIndexOf('/', resource.length - (hasTrailingSlash ? 2 : 1))) + '/';
html = html + '<li><a href="' + internals.pathEncode(parent) + '">Parent Directory</a></li>';
}

for (let i = 0; i < files.length; ++i) {
if (settings.showHidden ||
!internals.isFileHidden(files[i])) {
for (let i = 0; i < files.length; ++i) {
if (settings.showHidden ||
!internals.isFileHidden(files[i])) {

html = html + '<li><a href="' + internals.pathEncode(resource + (selection && !hasTrailingSlash ? '/' : '') + files[i]) + '">' + Hoek.escapeHtml(files[i]) + '</a></li>';
}
html = html + '<li><a href="' + internals.pathEncode(resource + (selection && !hasTrailingSlash ? '/' : '') + files[i]) + '">' + Hoek.escapeHtml(files[i]) + '</a></li>';
}
}

html = html + '</ul></body></html>';
html = html + '</ul></body></html>';

return reply(request.generateResponse(html));
});
return reply(request.generateResponse(html));
};


Expand Down
98 changes: 47 additions & 51 deletions lib/etag.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

const Crypto = require('crypto');
const Boom = require('boom');
const Hoek = require('hoek');
const LruCache = require('lru-cache');


Expand All @@ -15,11 +14,21 @@ const internals = {
};


internals.computeHashed = function (response, stat, next) {
internals.streamEnd = function (stream) {

return new Promise((resolve, reject) => {

stream.on('end', resolve);
stream.on('error', reject);
});
};


internals.computeHashed = async function (response, stat) {

const etags = response.request.server.plugins.inert._etags;
if (!etags) {
return next(null, null);
return null;
}

// Use stat info for an LRU cache key.
Expand All @@ -31,93 +40,80 @@ internals.computeHashed = function (response, stat, next) {

const cachedEtag = etags.get(cachekey);
if (cachedEtag) {
return next(null, cachedEtag);
return cachedEtag;
}

let nexts = internals.pendings[cachekey];
if (nexts) {
return nexts.push(next);
let promise = internals.pendings[cachekey];
if (promise) {
return await promise;
}

// Start hashing

nexts = [next];
internals.pendings[cachekey] = nexts;
const compute = async () => {

internals.hashFile(response, (err, hash) => {

if (!err) {
try {
const hash = await internals.hashFile(response);
etags.set(cachekey, hash);

return hash;
}
finally {
delete internals.pendings[cachekey];
}
};

// Call pending callbacks
internals.pendings[cachekey] = promise = compute();

delete internals.pendings[cachekey];
for (let i = 0; i < nexts.length; ++i) {
Hoek.nextTick(nexts[i])(err, hash);
}
});
return await promise;
};


internals.hashFile = function (response, callback) {
internals.hashFile = async function (response) {

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

const fileStream = response.source.file.createReadStream({ autoClose: false });
fileStream.pipe(hash);

let done = function (err) {

if (err) {
return callback(Boom.boomify(err, { message: 'Failed to hash file' }));
}

return callback(null, hash.read());
};

done = Hoek.once(done);

fileStream.on('end', done);
fileStream.on('error', done);
try {
await internals.streamEnd(fileStream);
return hash.read();
}
catch (err) {
throw Boom.boomify(err, { message: 'Failed to hash file' });
}
};


internals.computeSimple = function (response, stat, next) {
internals.computeSimple = function (response, stat) {

const size = stat.size.toString(16);
const mtime = stat.mtime.getTime().toString(16);

return next(null, size + '-' + mtime);
return size + '-' + mtime;
};


exports.apply = function (response, stat, next) {
exports.apply = async function (response, stat) {

const etagMethod = response.source.settings.etagMethod;
if (etagMethod === false) {
return next();
return;
}

const applyEtag = (err, etag) => {

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

if (etag !== null) {
response.etag(etag, { vary: true });
}

return next();
};

let etag;
if (etagMethod === 'simple') {
return internals.computeSimple(response, stat, applyEtag);
etag = internals.computeSimple(response, stat);
}
else {
etag = await internals.computeHashed(response, stat);
}

return internals.computeHashed(response, stat, applyEtag);
if (etag !== null) {
response.etag(etag, { vary: true });
}
};


Expand Down
Loading

0 comments on commit c07e967

Please sign in to comment.