Comparing version 3.2.1 to 4.0.0
@@ -0,10 +1,12 @@ | ||
'use strict'; | ||
// Load modules | ||
var Fs = require('fs'); | ||
var Path = require('path'); | ||
var Boom = require('boom'); | ||
var Hoek = require('hoek'); | ||
var Items = require('items'); | ||
var Joi = require('joi'); | ||
var File = require('./file'); | ||
const Fs = require('fs'); | ||
const Path = require('path'); | ||
const Boom = require('boom'); | ||
const Hoek = require('hoek'); | ||
const Items = require('items'); | ||
const Joi = require('joi'); | ||
const File = require('./file'); | ||
@@ -14,3 +16,3 @@ | ||
var internals = {}; | ||
const internals = {}; | ||
@@ -32,12 +34,12 @@ | ||
var settings = Joi.attempt(options, internals.schema, 'Invalid directory handler options (' + route.path + ')'); | ||
Hoek.assert(route.path[route.path.length - 1] === '}', 'The route path must end with a parameter:', route.path); | ||
const settings = Joi.attempt(options, internals.schema, 'Invalid directory handler options (' + route.path + ')'); | ||
Hoek.assert(route.path[route.path.length - 1] === '}', 'The route path for a directory handler must end with a parameter:', route.path); | ||
var normalize = function (paths) { | ||
const normalize = (paths) => { | ||
var normalized = []; | ||
for (var i = 0, il = paths.length; i < il; ++i) { | ||
var path = paths[i]; | ||
const normalized = []; | ||
for (let i = 0; i < paths.length; ++i) { | ||
let path = paths[i]; | ||
if (!Hoek.isAbsolutePath(path)) { | ||
if (!Path.isAbsolute(path)) { | ||
path = Path.join(route.settings.files.relativeTo, path); | ||
@@ -52,13 +54,13 @@ } | ||
var normalized = (Array.isArray(settings.path) ? normalize(settings.path) : []); // Array or function | ||
const normalized = (Array.isArray(settings.path) ? normalize(settings.path) : []); // Array or function | ||
var indexNames = (settings.index === true) ? ['index.html'] : (settings.index || []); | ||
const indexNames = (settings.index === true) ? ['index.html'] : (settings.index || []); | ||
// Declare handler | ||
var handler = function (request, reply) { | ||
const handler = (request, reply) => { | ||
var paths = normalized; | ||
let paths = normalized; | ||
if (typeof settings.path === 'function') { | ||
var result = settings.path.call(null, request); | ||
const result = settings.path.call(null, request); | ||
if (result instanceof Error) { | ||
@@ -81,12 +83,3 @@ return reply(result); | ||
var selection = null; | ||
var lastParam = request.paramsArray[request.paramsArray.length - 1]; | ||
if (lastParam) { | ||
if (lastParam.indexOf('..') !== -1) { | ||
return reply(Boom.forbidden()); | ||
} | ||
selection = lastParam; | ||
} | ||
const selection = request.paramsArray[request.paramsArray.length - 1]; | ||
if (selection && | ||
@@ -101,12 +94,18 @@ !settings.showHidden && | ||
var resource = request.path; | ||
var hasTrailingSlash = (resource[resource.length - 1] === '/'); | ||
var fileOptions = { lookupCompressed: settings.lookupCompressed, etagMethod: settings.etagMethod }; | ||
const resource = request.path; | ||
const hasTrailingSlash = resource.endsWith('/'); | ||
const fileOptions = { | ||
confine: null, | ||
lookupCompressed: settings.lookupCompressed, | ||
etagMethod: settings.etagMethod | ||
}; | ||
Items.serial(paths, function (path, nextPath) { | ||
Items.serial(paths, (baseDir, nextPath) => { | ||
path = Path.join(path, selection || ''); | ||
fileOptions.confine = baseDir; | ||
File.load(path, request, fileOptions, function (response) { | ||
let path = selection || ''; | ||
File.load(path, request, fileOptions, (response) => { | ||
// File loaded successfully | ||
@@ -120,3 +119,3 @@ | ||
var err = response; | ||
const err = response; | ||
if (err.output.statusCode === 404) { | ||
@@ -131,3 +130,3 @@ if (!settings.defaultExtension) { | ||
return File.load(path + '.' + settings.defaultExtension, request, fileOptions, function (extResponse) { | ||
return File.load(path + '.' + settings.defaultExtension, request, fileOptions, (extResponse) => { | ||
@@ -163,6 +162,6 @@ if (!extResponse.isBoom) { | ||
Items.serial(indexNames, function (indexName, nextIndex) { | ||
Items.serial(indexNames, (indexName, nextIndex) => { | ||
var indexFile = Path.join(path, indexName); | ||
File.load(indexFile, request, fileOptions, function (indexResponse) { | ||
const indexFile = Path.join(path, indexName); | ||
File.load(indexFile, request, fileOptions, (indexResponse) => { | ||
@@ -177,3 +176,3 @@ // File loaded successfully | ||
var err = indexResponse; | ||
const err = indexResponse; | ||
if (err.output.statusCode !== 404) { | ||
@@ -188,3 +187,3 @@ return reply(Boom.badImplementation(indexName + ' is a directory')); | ||
}, | ||
function (/* err */) { | ||
(/* err */) => { | ||
@@ -197,7 +196,7 @@ // None of the index files were found | ||
return internals.generateListing(path, resource, selection, hasTrailingSlash, settings, request, reply); | ||
return internals.generateListing(Path.join(baseDir, path), resource, selection, hasTrailingSlash, settings, request, reply); | ||
}); | ||
}); | ||
}, | ||
function (/* err */) { | ||
(/* err */) => { | ||
@@ -214,3 +213,3 @@ return reply(Boom.notFound()); | ||
Fs.readdir(path, function (err, files) { | ||
Fs.readdir(path, (err, files) => { | ||
@@ -222,19 +221,19 @@ if (err) { | ||
resource = decodeURIComponent(resource); | ||
var display = Hoek.escapeHtml(resource); | ||
var html = '<html><head><title>' + display + '</title></head><body><h1>Directory: ' + display + '</h1><ul>'; | ||
const display = Hoek.escapeHtml(resource); | ||
let html = '<html><head><title>' + display + '</title></head><body><h1>Directory: ' + display + '</h1><ul>'; | ||
if (selection) { | ||
var parent = resource.substring(0, resource.lastIndexOf('/', resource.length - (hasTrailingSlash ? 2 : 1))) + '/'; | ||
html += '<li><a href="' + internals.pathEncode(parent) + '">Parent Directory</a></li>'; | ||
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 (var i = 0, il = files.length; i < il; ++i) { | ||
for (let i = 0; i < files.length; ++i) { | ||
if (settings.showHidden || | ||
!internals.isFileHidden(files[i])) { | ||
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 += '</ul></body></html>'; | ||
html = html + '</ul></body></html>'; | ||
@@ -248,3 +247,3 @@ return reply(request.generateResponse(html)); | ||
return /(^|[\\\/])\.([^\\\/]|[\\\/]?$)/.test(path); // Starts with a '.' or contains '/.' or '\.', and not followed by a '/' or '\' or end | ||
return /(^|[\\\/])\.([^.\\\/]|\.[^\\\/])/.test(path); // Starts with a '.' or contains '/.' or '\.', which is not followed by a '/' or '\' or '.' | ||
}; | ||
@@ -251,0 +250,0 @@ |
@@ -0,8 +1,10 @@ | ||
'use strict'; | ||
// Load modules | ||
var Fs = require('fs'); | ||
var Crypto = require('crypto'); | ||
var Boom = require('boom'); | ||
var Hoek = require('hoek'); | ||
var LruCache = require('lru-cache'); | ||
const Fs = require('fs'); | ||
const Crypto = require('crypto'); | ||
const Boom = require('boom'); | ||
const Hoek = require('hoek'); | ||
const LruCache = require('lru-cache'); | ||
@@ -12,3 +14,3 @@ | ||
var internals = {}; | ||
const internals = {}; | ||
@@ -18,3 +20,3 @@ | ||
var etags = response.request.server.plugins.inert._etags; | ||
const etags = response.request.server.plugins.inert._etags; | ||
if (!etags) { | ||
@@ -26,8 +28,8 @@ return next(null, null); | ||
var path = response.source.path; | ||
var cachekey = [path, stat.ino, stat.size, stat.mtime.getTime()].join('-'); | ||
const path = response.source.path; | ||
const cachekey = [path, stat.ino, stat.size, stat.mtime.getTime()].join('-'); | ||
// The etag hashes the file contents in order to be consistent across distributed deployments | ||
var cachedEtag = etags.get(cachekey); | ||
const cachedEtag = etags.get(cachekey); | ||
if (cachedEtag) { | ||
@@ -37,5 +39,5 @@ return next(null, cachedEtag); | ||
var pendings = response.request.server.plugins.inert._pendings; | ||
var pendingsId = '+' + cachekey; // Prefix to avoid conflicts with JS internals (e.g. __proto__) | ||
var nexts = pendings[pendingsId]; | ||
const pendings = response.request.server.plugins.inert._pendings; | ||
const pendingsId = '+' + cachekey; // Prefix to avoid conflicts with JS internals (e.g. __proto__) | ||
let nexts = pendings[pendingsId]; | ||
if (nexts) { | ||
@@ -50,3 +52,3 @@ return nexts.push(next); | ||
internals.hashFile(response, function (err, hash) { | ||
internals.hashFile(response, (err, hash) => { | ||
@@ -60,3 +62,3 @@ if (!err) { | ||
delete pendings[pendingsId]; | ||
for (var i = 0, il = nexts.length; i < il; ++i) { | ||
for (let i = 0; i < nexts.length; ++i) { | ||
Hoek.nextTick(nexts[i])(err, hash); | ||
@@ -70,9 +72,9 @@ } | ||
var hash = Crypto.createHash('sha1'); | ||
const hash = Crypto.createHash('sha1'); | ||
hash.setEncoding('hex'); | ||
var fileStream = Fs.createReadStream(response.source.path, { fd: response.source.fd, autoClose: false }); | ||
const fileStream = Fs.createReadStream(response.source.path, { fd: response.source.fd, autoClose: false }); | ||
fileStream.pipe(hash); | ||
var done = function (err) { | ||
let done = function (err) { | ||
@@ -95,4 +97,4 @@ if (err) { | ||
var size = stat.size.toString(16); | ||
var mtime = stat.mtime.getTime().toString(16); | ||
const size = stat.size.toString(16); | ||
const mtime = stat.mtime.getTime().toString(16); | ||
@@ -105,3 +107,3 @@ return next(null, size + '-' + mtime); | ||
var etagMethod = response.source.settings.etagMethod; | ||
const etagMethod = response.source.settings.etagMethod; | ||
if (etagMethod === false) { | ||
@@ -111,3 +113,3 @@ return next(); | ||
var applyEtag = function (err, etag) { | ||
const applyEtag = (err, etag) => { | ||
@@ -114,0 +116,0 @@ if (err) { |
@@ -0,10 +1,12 @@ | ||
'use strict'; | ||
// Load modules | ||
var Fs = require('fs'); | ||
var Path = require('path'); | ||
var Ammo = require('ammo'); | ||
var Boom = require('boom'); | ||
var Hoek = require('hoek'); | ||
var Joi = require('joi'); | ||
var Etag = require('./etag'); | ||
const Fs = require('fs'); | ||
const Path = require('path'); | ||
const Ammo = require('ammo'); | ||
const Boom = require('boom'); | ||
const Hoek = require('hoek'); | ||
const Joi = require('joi'); | ||
const Etag = require('./etag'); | ||
@@ -14,3 +16,3 @@ | ||
var internals = {}; | ||
const internals = {}; | ||
@@ -23,2 +25,3 @@ | ||
path: Joi.alternatives(Joi.string(), Joi.func()).required(), | ||
confine: Joi.alternatives(Joi.string(), Joi.boolean()).default(true), | ||
filename: Joi.string(), | ||
@@ -35,9 +38,10 @@ mode: Joi.string().valid('attachment', 'inline').allow(false), | ||
var settings = Joi.attempt(options, internals.schema, 'Invalid file handler options (' + route.path + ')'); | ||
settings = (typeof options !== 'object' ? { path: options } : settings); | ||
let settings = Joi.attempt(options, internals.schema, 'Invalid file handler options (' + route.path + ')'); | ||
settings = (typeof options !== 'object' ? { path: options, confine: '.' } : settings); | ||
settings.confine = settings.confine === true ? '.' : settings.confine; | ||
Hoek.assert(typeof settings.path !== 'string' || settings.path[settings.path.length - 1] !== '/', 'File path cannot end with a \'/\':', route.path); | ||
var handler = function (request, reply) { | ||
const handler = (request, reply) => { | ||
var path = (typeof settings.path === 'function' ? settings.path(request) : settings.path); | ||
const path = (typeof settings.path === 'function' ? settings.path(request) : settings.path); | ||
return reply(exports.response(path, settings, request)); | ||
@@ -52,3 +56,3 @@ }; | ||
var response = exports.response(path, options, request, true); | ||
const response = exports.response(path, options, request, true); | ||
return internals.prepare(response, callback); | ||
@@ -60,7 +64,19 @@ }; | ||
options = options || {}; | ||
Hoek.assert(!options.mode || ['attachment', 'inline'].indexOf(options.mode) !== -1, 'options.mode must be either false, attachment, or inline'); | ||
var source = { | ||
path: Path.normalize(Hoek.isAbsolutePath(path) ? path : Path.join(request.route.settings.files.relativeTo, path)), | ||
if (options.confine) { | ||
const confineDir = Path.resolve(request.route.settings.files.relativeTo, options.confine); | ||
path = Path.isAbsolute(path) ? Path.normalize(path) : Path.join(confineDir, path); | ||
// Verify that resolved path is within confineDir | ||
if (path.lastIndexOf(confineDir, 0) !== 0) { | ||
path = null; | ||
} | ||
} | ||
else { | ||
path = Path.isAbsolute(path) ? Path.normalize(path) : Path.join(request.route.settings.files.relativeTo, path); | ||
} | ||
const source = { | ||
path: path, | ||
settings: options, | ||
@@ -71,3 +87,3 @@ stat: null, | ||
var prepare = _preloaded ? null : internals.prepare; | ||
const prepare = _preloaded ? null : internals.prepare; | ||
@@ -80,5 +96,13 @@ return request.generateResponse(source, { variety: 'file', marshal: internals.marshal, prepare: prepare, close: internals.close }); | ||
var path = response.source.path; | ||
internals.openStat(path, 'r', function (err, fd, stat) { | ||
const path = response.source.path; | ||
if (path === null) { | ||
return process.nextTick(() => { | ||
return callback(Boom.forbidden(null, 'EACCES')); | ||
}); | ||
} | ||
internals.openStat(path, 'r', (err, fd, stat) => { | ||
if (err) { | ||
@@ -98,7 +122,7 @@ return callback(err); | ||
if (response.source.settings.mode) { | ||
var fileName = response.source.settings.filename || Path.basename(path); | ||
const fileName = response.source.settings.filename || Path.basename(path); | ||
response.header('content-disposition', response.source.settings.mode + '; filename=' + encodeURIComponent(fileName)); | ||
} | ||
Etag.apply(response, stat, function (err) { | ||
Etag.apply(response, stat, (err) => { | ||
@@ -125,4 +149,4 @@ if (err) { | ||
var gzFile = response.source.path + '.gz'; | ||
internals.openStat(gzFile, 'r', function (err, fd, stat) { | ||
const gzFile = response.source.path + '.gz'; | ||
internals.openStat(gzFile, 'r', (err, fd, stat) => { | ||
@@ -147,5 +171,5 @@ if (err) { | ||
var request = response.request; | ||
var length = response.headers['content-length']; | ||
var range = null; | ||
const request = response.request; | ||
const length = response.headers['content-length']; | ||
let range = null; | ||
@@ -161,4 +185,4 @@ if (request.headers.range && length) { | ||
var mime = request.server.mime.type(response.headers['content-type'] || 'application/octet-stream'); | ||
var encoding = (request.connection.settings.compression && mime.compressible && !response.headers['content-encoding'] ? request.info.acceptEncoding : null); | ||
const mime = request.server.mime.type(response.headers['content-type'] || 'application/octet-stream'); | ||
const encoding = (request.connection.settings.compression && mime.compressible && !response.headers['content-encoding'] ? request.info.acceptEncoding : null); | ||
@@ -169,5 +193,5 @@ if (encoding === 'identity' || !encoding) { | ||
var ranges = Ammo.header(request.headers.range, length); | ||
const ranges = Ammo.header(request.headers.range, length); | ||
if (!ranges) { | ||
var error = Boom.rangeNotSatisfiable(); | ||
const error = Boom.rangeNotSatisfiable(); | ||
error.output.headers['content-range'] = 'bytes */' + length; | ||
@@ -199,5 +223,5 @@ return callback(error); | ||
var options = { fd: response.source.fd, start: 0 }; | ||
const options = { fd: response.source.fd, start: 0 }; | ||
internals.addContentRange(response, function (err, range) { | ||
internals.addContentRange(response, (err, range) => { | ||
@@ -213,3 +237,3 @@ if (err) { | ||
var fileStream = Fs.createReadStream(path, options); | ||
const fileStream = Fs.createReadStream(path, options); | ||
response.source.fd = null; // Claim descriptor | ||
@@ -224,3 +248,3 @@ | ||
Fs.open(path, mode, function (err, fd) { | ||
Fs.open(path, mode, (err, fd) => { | ||
@@ -239,3 +263,3 @@ if (err) { | ||
Fs.fstat(fd, function (err, stat) { | ||
Fs.fstat(fd, (err, stat) => { | ||
@@ -242,0 +266,0 @@ if (err) { |
@@ -0,7 +1,9 @@ | ||
'use strict'; | ||
// Load modules | ||
var Directory = require('./directory'); | ||
var Etag = require('./etag'); | ||
var File = require('./file'); | ||
var Hoek = require('hoek'); | ||
const Directory = require('./directory'); | ||
const Etag = require('./etag'); | ||
const File = require('./file'); | ||
const Hoek = require('hoek'); | ||
@@ -11,3 +13,3 @@ | ||
var internals = { | ||
const internals = { | ||
defaults: { | ||
@@ -21,3 +23,3 @@ etagsCacheMaxSize: 1000 | ||
var settings = Hoek.applyToDefaults(internals.defaults, options); | ||
const settings = Hoek.applyToDefaults(internals.defaults, options); | ||
@@ -32,2 +34,9 @@ server.expose('_etags', settings.etagsCacheMaxSize ? new Etag.Cache(settings.etagsCacheMaxSize) : null); | ||
// Set correct confine value | ||
responseOptions = responseOptions || {}; | ||
if (typeof responseOptions.confine === 'undefined' || responseOptions.confine === true) { | ||
responseOptions.confine = '.'; | ||
} | ||
return this.response(File.response(path, responseOptions, this.request)); | ||
@@ -39,2 +48,3 @@ }); | ||
exports.register.attributes = { | ||
@@ -41,0 +51,0 @@ pkg: require('../package.json'), |
{ | ||
"name": "inert", | ||
"description": "Static file and directory handlers plugin for hapi.js", | ||
"version": "3.2.1", | ||
"version": "4.0.0", | ||
"repository": "git://github.com/hapijs/inert", | ||
@@ -15,16 +15,16 @@ "main": "lib/index.js", | ||
"engines": { | ||
"node": ">=0.10.40" | ||
"node": ">=4.0.0" | ||
}, | ||
"dependencies": { | ||
"ammo": "1.x.x", | ||
"boom": "2.x.x", | ||
"hoek": "2.x.x", | ||
"items": "1.x.x", | ||
"joi": "^6.7.x", | ||
"lru-cache": "2.7.x" | ||
"ammo": "2.x.x", | ||
"boom": "3.x.x", | ||
"hoek": "4.x.x", | ||
"items": "2.x.x", | ||
"joi": "8.x.x", | ||
"lru-cache": "4.0.x" | ||
}, | ||
"devDependencies": { | ||
"code": "1.x.x", | ||
"hapi": "9.x.x", | ||
"lab": "6.x.x" | ||
"code": "2.x.x", | ||
"hapi": "13.x.x", | ||
"lab": "10.x.x" | ||
}, | ||
@@ -31,0 +31,0 @@ "scripts": { |
@@ -42,7 +42,7 @@ # inert | ||
```js | ||
var Path = require('path'); | ||
var Hapi = require('hapi'); | ||
var Inert = require('inert'); | ||
const Path = require('path'); | ||
const Hapi = require('hapi'); | ||
const Inert = require('inert'); | ||
var server = new Hapi.Server({ | ||
const server = new Hapi.Server({ | ||
connections: { | ||
@@ -58,3 +58,3 @@ routes: { | ||
server.register(Inert, function () {}); | ||
server.register(Inert, () => {}); | ||
@@ -73,3 +73,3 @@ server.route({ | ||
server.start(function (err) { | ||
server.start((err) => { | ||
@@ -108,3 +108,3 @@ if (err) { | ||
var path = 'plain.txt'; | ||
let path = 'plain.txt'; | ||
if (request.headers['x-magic'] === 'sekret') { | ||
@@ -120,3 +120,3 @@ path = 'awesome.png'; | ||
var response = request.response; | ||
const response = request.response; | ||
if (response.isBoom && | ||
@@ -132,6 +132,2 @@ response.output.statusCode === 404) { | ||
Note that paths for files served using the `reply.file()` handler are **NOT** guarded against | ||
access outside the `files.relativeTo` directory, so be careful to guard against malevolent user | ||
input. | ||
## Usage | ||
@@ -159,2 +155,6 @@ | ||
- `options` - optional settings: | ||
- `confine` - serve file relative to this directory and returns `403 Forbidden` if the | ||
`path` resolves outside the `confine` directory. | ||
Defaults to `true` which uses the `relativeTo` route option as the `confine`. | ||
Set to `false` to disable this security feature. | ||
- `filename` - an optional filename to specify if sending a 'Content-Disposition' header, | ||
@@ -192,2 +192,6 @@ defaults to the basename of `path` | ||
- `path` - a path string or function as described above (required). | ||
- `confine` - serve file relative to this directory and returns `403 Forbidden` if the | ||
`path` resolves outside the `confine` directory. | ||
Defaults to `true` which uses the `relativeTo` route option as the `confine`. | ||
Set to `false` to disable this security feature. | ||
- `filename` - an optional filename to specify if sending a 'Content-Disposition' | ||
@@ -194,0 +198,0 @@ header, defaults to the basename of `path` |
@@ -0,12 +1,14 @@ | ||
'use strict'; | ||
// Load modules | ||
var Fs = require('fs'); | ||
var Os = require('os'); | ||
var Path = require('path'); | ||
var Boom = require('boom'); | ||
var Code = require('code'); | ||
var Hapi = require('hapi'); | ||
var Hoek = require('hoek'); | ||
var Inert = require('..'); | ||
var Lab = require('lab'); | ||
const Fs = require('fs'); | ||
const Os = require('os'); | ||
const Path = require('path'); | ||
const Boom = require('boom'); | ||
const Code = require('code'); | ||
const Hapi = require('hapi'); | ||
const Hoek = require('hoek'); | ||
const Inert = require('..'); | ||
const Lab = require('lab'); | ||
@@ -16,3 +18,3 @@ | ||
var internals = {}; | ||
const internals = {}; | ||
@@ -22,15 +24,15 @@ | ||
var lab = exports.lab = Lab.script(); | ||
var describe = lab.describe; | ||
var it = lab.it; | ||
var expect = Code.expect; | ||
const lab = exports.lab = Lab.script(); | ||
const describe = lab.describe; | ||
const it = lab.it; | ||
const expect = Code.expect; | ||
describe('directory', function () { | ||
describe('directory', () => { | ||
describe('handler()', function () { | ||
describe('handler()', () => { | ||
var provisionServer = function (connection, debug) { | ||
const provisionServer = (connection, debug) => { | ||
var server = new Hapi.Server({ debug: debug }); | ||
const server = new Hapi.Server({ debug: debug }); | ||
server.connection(connection || { routes: { files: { relativeTo: __dirname } }, router: { stripTrailingSlash: false } }); | ||
@@ -41,8 +43,8 @@ server.register(Inert, Hoek.ignore); | ||
it('returns a 403 when no index exists and listing is disabled', function (done) { | ||
it('returns a 403 when no index exists and listing is disabled', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directory/{path*}', handler: { directory: { path: '.' } } }); // Use '.' to test path normalization | ||
server.inject('/directory/', function (res) { | ||
server.inject('/directory/', (res) => { | ||
@@ -54,8 +56,8 @@ expect(res.statusCode).to.equal(403); | ||
it('returns a 403 when requesting a path containing \'..\'', function (done) { | ||
it('returns a 403 when requesting a path containing \'..\'', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directory/{path*}', handler: { directory: { path: './' } } }); | ||
server.inject('/directory/..', function (res) { | ||
server.inject('/directory/..', (res) => { | ||
@@ -67,8 +69,8 @@ expect(res.statusCode).to.equal(403); | ||
it('returns a 404 when requesting an unknown file within a directory', function (done) { | ||
it('returns a 404 when requesting an unknown file within a directory', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directory/{path*}', handler: { directory: { path: './' } } }); | ||
server.inject('/directory/xyz', function (res) { | ||
server.inject('/directory/xyz', (res) => { | ||
@@ -80,8 +82,8 @@ expect(res.statusCode).to.equal(404); | ||
it('returns a file when requesting a file from the directory', function (done) { | ||
it('returns a file when requesting a file from the directory', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directory/{path*}', handler: { directory: { path: './' } } }); | ||
server.inject('/directory/directory.js', function (res) { | ||
server.inject('/directory/directory.js', (res) => { | ||
@@ -94,8 +96,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a file when requesting a file from multi directory setup', function (done) { | ||
it('returns a file when requesting a file from multi directory setup', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/multiple/{path*}', handler: { directory: { path: ['./', '../'], listing: true } } }); | ||
server.inject('/multiple/package.json', function (res) { | ||
server.inject('/multiple/package.json', (res) => { | ||
@@ -108,5 +110,5 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a file when requesting a file from multi directory function response', function (done) { | ||
it('returns a file when requesting a file from multi directory function response', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ | ||
@@ -117,3 +119,3 @@ method: 'GET', | ||
directory: { | ||
path: function () { | ||
path: () => { | ||
@@ -127,3 +129,3 @@ return ['./', '../']; | ||
server.inject('/multiple/package.json', function (res) { | ||
server.inject('/multiple/package.json', (res) => { | ||
@@ -136,8 +138,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns the correct file when requesting a file from a child directory', function (done) { | ||
it('returns the correct file when requesting a file from a child directory', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directory/{path*}', handler: { directory: { path: './' } } }); | ||
server.inject('/directory/directory/index.html', function (res) { | ||
server.inject('/directory/directory/index.html', (res) => { | ||
@@ -150,8 +152,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns the correct listing links when viewing top level path', function (done) { | ||
it('returns the correct listing links when viewing top level path', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/{path*}', handler: { directory: { path: './', index: true, listing: true } } }); | ||
server.inject('/', function (res) { | ||
server.inject('/', (res) => { | ||
@@ -164,8 +166,8 @@ expect(res.statusCode).to.equal(200); | ||
it('does not contain any double / when viewing sub path listing', function (done) { | ||
it('does not contain any double / when viewing sub path listing', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/showindex/{path*}', handler: { directory: { path: './', index: true, listing: true } } }); | ||
server.inject('/showindex/', function (res) { | ||
server.inject('/showindex/', (res) => { | ||
@@ -178,8 +180,8 @@ expect(res.statusCode).to.equal(200); | ||
it('has the correct link to sub folders when inside of a sub folder listing', function (done) { | ||
it('has the correct link to sub folders when inside of a sub folder listing', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/showindex/{path*}', handler: { directory: { path: './', index: true, listing: true } } }); | ||
server.inject('/showindex/directory/subdir/', function (res) { | ||
server.inject('/showindex/directory/subdir/', (res) => { | ||
@@ -192,8 +194,8 @@ expect(res.statusCode).to.equal(200); | ||
it('has the correct link to a sub folder with spaces when inside of a sub folder listing', function (done) { | ||
it('has the correct link to a sub folder with spaces when inside of a sub folder listing', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/showindex/{path*}', handler: { directory: { path: './', index: true, listing: true } } }); | ||
server.inject('/showindex/directory/subdir/', function (res) { | ||
server.inject('/showindex/directory/subdir/', (res) => { | ||
@@ -206,8 +208,8 @@ expect(res.statusCode).to.equal(200); | ||
it('has the correct link to a file when inside of a listing of a sub folder that is inside a subfolder with spaces', function (done) { | ||
it('has the correct link to a file when inside of a listing of a sub folder that is inside a subfolder with spaces', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/showindex/{path*}', handler: { directory: { path: './', index: true, listing: true } } }); | ||
server.inject('/showindex/directory/subdir/sub%20subdir%3D/subsubsubdir/', function (res) { | ||
server.inject('/showindex/directory/subdir/sub%20subdir%3D/subsubsubdir/', (res) => { | ||
@@ -220,8 +222,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns the correct file when requesting a file from a directory with spaces', function (done) { | ||
it('returns the correct file when requesting a file from a directory with spaces', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directory/{path*}', handler: { directory: { path: './', index: true, listing: true } } }); | ||
server.inject('/directory/directory/subdir/sub%20subdir%3D/test%24.json', function (res) { | ||
server.inject('/directory/directory/subdir/sub%20subdir%3D/test%24.json', (res) => { | ||
@@ -234,8 +236,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns the correct file when requesting a file from a directory that its parent directory has spaces', function (done) { | ||
it('returns the correct file when requesting a file from a directory that its parent directory has spaces', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directory/{path*}', handler: { directory: { path: './', index: true, listing: true } } }); | ||
server.inject('/directory/directory/subdir/sub%20subdir%3D/subsubsubdir/test.txt', function (res) { | ||
server.inject('/directory/directory/subdir/sub%20subdir%3D/subsubsubdir/test.txt', (res) => { | ||
@@ -248,8 +250,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a 403 when index and listing are disabled', function (done) { | ||
it('returns a 403 when index and listing are disabled', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directoryx/{path*}', handler: { directory: { path: '../', index: false } } }); | ||
server.inject('/directoryx/', function (res) { | ||
server.inject('/directoryx/', (res) => { | ||
@@ -261,8 +263,8 @@ expect(res.statusCode).to.equal(403); | ||
it('returns a list of files when listing is enabled', function (done) { | ||
it('returns a list of files when listing is enabled', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directorylist/{path*}', handler: { directory: { path: '../', listing: true } } }); | ||
server.inject('/directorylist/', function (res) { | ||
server.inject('/directorylist/', (res) => { | ||
@@ -275,8 +277,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a list of files for subdirectory', function (done) { | ||
it('returns a list of files for subdirectory', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directorylist/{path*}', handler: { directory: { path: '../', listing: true } } }); | ||
server.inject('/directorylist/test/', function (res) { | ||
server.inject('/directorylist/test/', (res) => { | ||
@@ -289,8 +291,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a list of files when listing is enabled and index disabled', function (done) { | ||
it('returns a list of files when listing is enabled and index disabled', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directorylistx/{path*}', handler: { directory: { path: '../', listing: true, index: false } } }); | ||
server.inject('/directorylistx/', function (res) { | ||
server.inject('/directorylistx/', (res) => { | ||
@@ -303,8 +305,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns the "index.html" index file when found and default index enabled', function (done) { | ||
it('returns the "index.html" index file when found and default index enabled', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directoryIndex/{path*}', handler: { directory: { path: './directory/' } } }); | ||
server.inject('/directoryIndex/', function (res) { | ||
server.inject('/directoryIndex/', (res) => { | ||
@@ -317,8 +319,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns the index file when found and single custom index file specified', function (done) { | ||
it('returns the index file when found and single custom index file specified', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directoryIndex/{path*}', handler: { directory: { path: './directory/', index: 'index.js' } } }); | ||
server.inject('/directoryIndex/', function (res) { | ||
server.inject('/directoryIndex/', (res) => { | ||
@@ -331,8 +333,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns the first index file found when an array of index files is specified', function (done) { | ||
it('returns the first index file found when an array of index files is specified', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directoryIndex/{path*}', handler: { directory: { path: './directory/', index: ['default.html', 'index.js', 'non.existing'] } } }); | ||
server.inject('/directoryIndex/', function (res) { | ||
server.inject('/directoryIndex/', (res) => { | ||
@@ -345,8 +347,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a 403 when listing is disabled and a custom index file is specified but not found', function (done) { | ||
it('returns a 403 when listing is disabled and a custom index file is specified but not found', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directoryIndex/{path*}', handler: { directory: { path: './directory/', index: 'default.html' } } }); | ||
server.inject('/directoryIndex/', function (res) { | ||
server.inject('/directoryIndex/', (res) => { | ||
@@ -358,8 +360,8 @@ expect(res.statusCode).to.equal(403); | ||
it('returns a 403 when listing is disabled and an array of index files is specified but none were found', function (done) { | ||
it('returns a 403 when listing is disabled and an array of index files is specified but none were found', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directoryIndex/{path*}', handler: { directory: { path: './directory/', index: ['default.html', 'non.existing'] } } }); | ||
server.inject('/directoryIndex/', function (res) { | ||
server.inject('/directoryIndex/', (res) => { | ||
@@ -371,8 +373,8 @@ expect(res.statusCode).to.equal(403); | ||
it('returns the index when served from a hidden folder', function (done) { | ||
it('returns the index when served from a hidden folder', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/{path*}', handler: { directory: { path: './directory/.dot' } } }); | ||
server.inject('/index.html', function (res) { | ||
server.inject('/index.html', (res) => { | ||
@@ -382,3 +384,3 @@ expect(res.statusCode).to.equal(200); | ||
server.inject('/', function (res2) { | ||
server.inject('/', (res2) => { | ||
@@ -392,8 +394,8 @@ expect(res2.statusCode).to.equal(200); | ||
it('returns listing when served from a hidden folder', function (done) { | ||
it('returns listing when served from a hidden folder', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/{path*}', handler: { directory: { path: './directory/.dot', index: false, listing: true } } }); | ||
server.inject('/', function (res) { | ||
server.inject('/', (res) => { | ||
@@ -406,8 +408,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a 500 when index.html is a directory', function (done) { | ||
it('returns a 500 when index.html is a directory', (done) => { | ||
var server = provisionServer(null, false); | ||
const server = provisionServer(null, false); | ||
server.route({ method: 'GET', path: '/directoryIndex/{path*}', handler: { directory: { path: './directory/' } } }); | ||
server.inject('/directoryIndex/invalid/', function (res) { | ||
server.inject('/directoryIndex/invalid/', (res) => { | ||
@@ -419,8 +421,8 @@ expect(res.statusCode).to.equal(500); | ||
it('returns a 500 when the custom index is a directory', function (done) { | ||
it('returns a 500 when the custom index is a directory', (done) => { | ||
var server = provisionServer(null, false); | ||
const server = provisionServer(null, false); | ||
server.route({ method: 'GET', path: '/directoryIndex/{path*}', handler: { directory: { path: './directory/', index: 'misc' } } }); | ||
server.inject('/directoryIndex/invalid/', function (res) { | ||
server.inject('/directoryIndex/invalid/', (res) => { | ||
@@ -432,5 +434,5 @@ expect(res.statusCode).to.equal(500); | ||
it('returns the correct file when using a fn directory handler', function (done) { | ||
it('returns the correct file when using a fn directory handler', (done) => { | ||
var directoryFn = function (request) { | ||
const directoryFn = (request) => { | ||
@@ -440,6 +442,6 @@ return '../lib'; | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directoryfn/{path?}', handler: { directory: { path: directoryFn } } }); | ||
server.inject('/directoryfn/index.js', function (res) { | ||
server.inject('/directoryfn/index.js', (res) => { | ||
@@ -452,8 +454,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns listing with hidden files when hidden files should be shown', function (done) { | ||
it('returns listing with hidden files when hidden files should be shown', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/showhidden/{path*}', handler: { directory: { path: './', showHidden: true, listing: true } } }); | ||
server.inject('/showhidden/', function (res) { | ||
server.inject('/showhidden/', (res) => { | ||
@@ -465,8 +467,8 @@ expect(res.payload).to.contain('.hidden'); | ||
it('returns listing without hidden files when hidden files should not be shown', function (done) { | ||
it('returns listing without hidden files when hidden files should not be shown', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/noshowhidden/{path*}', handler: { directory: { path: './', listing: true } } }); | ||
server.inject('/noshowhidden/', function (res) { | ||
server.inject('/noshowhidden/', (res) => { | ||
@@ -479,8 +481,8 @@ expect(res.payload).to.not.contain('.hidden'); | ||
it('returns a 404 response when requesting a hidden file when showHidden is disabled', function (done) { | ||
it('returns a 404 response when requesting a hidden file when showHidden is disabled', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/noshowhidden/{path*}', handler: { directory: { path: './', listing: true } } }); | ||
server.inject('/noshowhidden/.hidden', function (res) { | ||
server.inject('/noshowhidden/.hidden', (res) => { | ||
@@ -492,12 +494,12 @@ expect(res.statusCode).to.equal(404); | ||
it('returns a 404 response when requesting a file in a hidden directory when showHidden is disabled', function (done) { | ||
it('returns a 404 response when requesting a file in a hidden directory when showHidden is disabled', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/noshowhidden/{path*}', handler: { directory: { path: './directory', listing: true } } }); | ||
server.inject('/noshowhidden/.dot/index.html', function (res) { | ||
server.inject('/noshowhidden/.dot/index.html', (res) => { | ||
expect(res.statusCode).to.equal(404); | ||
server.inject('/noshowhidden/.dot/', function (res2) { | ||
server.inject('/noshowhidden/.dot/', (res2) => { | ||
@@ -510,8 +512,8 @@ expect(res2.statusCode).to.equal(404); | ||
it('returns a 404 response when requesting a hidden directory listing when showHidden is disabled', function (done) { | ||
it('returns a 404 response when requesting a hidden directory listing when showHidden is disabled', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/noshowhidden/{path*}', handler: { directory: { path: './directory', listing: true, index: false } } }); | ||
server.inject('/noshowhidden/.dot/', function (res) { | ||
server.inject('/noshowhidden/.dot/', (res) => { | ||
@@ -523,8 +525,8 @@ expect(res.statusCode).to.equal(404); | ||
it('returns a file when requesting a hidden file when showHidden is enabled', function (done) { | ||
it('returns a file when requesting a hidden file when showHidden is enabled', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/showhidden/{path*}', handler: { directory: { path: './', showHidden: true, listing: true } } }); | ||
server.inject('/showhidden/.hidden', function (res) { | ||
server.inject('/showhidden/.hidden', (res) => { | ||
@@ -536,8 +538,8 @@ expect(res.payload).to.contain('Ssssh!'); | ||
it('returns a a file when requesting a file in a hidden directory when showHidden is enabled', function (done) { | ||
it('returns a a file when requesting a file in a hidden directory when showHidden is enabled', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/noshowhidden/{path*}', handler: { directory: { path: './directory', showHidden: true, listing: true } } }); | ||
server.inject('/noshowhidden/.dot/index.html', function (res) { | ||
server.inject('/noshowhidden/.dot/index.html', (res) => { | ||
@@ -547,3 +549,3 @@ expect(res.statusCode).to.equal(200); | ||
server.inject('/noshowhidden/.dot/', function (res2) { | ||
server.inject('/noshowhidden/.dot/', (res2) => { | ||
@@ -557,8 +559,8 @@ expect(res2.statusCode).to.equal(200); | ||
it('redirects to the same path with / appended if asking for a directory', function (done) { | ||
it('redirects to the same path with / appended if asking for a directory', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/redirect/{path*}', handler: { directory: { path: './', index: true, listing: true } } }); | ||
server.inject('/redirect/directory/subdir', function (res) { | ||
server.inject('/redirect/directory/subdir', (res) => { | ||
@@ -571,8 +573,8 @@ expect(res.statusCode).to.equal(302); | ||
it('does not redirect to the same path with / appended redirectToSlash disabled', function (done) { | ||
it('does not redirect to the same path with / appended redirectToSlash disabled', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/redirect/{path*}', handler: { directory: { path: './', index: true, listing: true, redirectToSlash: false } } }); | ||
server.inject('http://example.com/redirect/directory/subdir', function (res) { | ||
server.inject('http://example.com/redirect/directory/subdir', (res) => { | ||
@@ -585,8 +587,8 @@ expect(res.statusCode).to.equal(200); | ||
it('does not redirect to the same path with / appended when server stripTrailingSlash is true', function (done) { | ||
it('does not redirect to the same path with / appended when server stripTrailingSlash is true', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: __dirname } }, router: { stripTrailingSlash: true } }); | ||
const server = provisionServer({ routes: { files: { relativeTo: __dirname } }, router: { stripTrailingSlash: true } }); | ||
server.route({ method: 'GET', path: '/redirect/{path*}', handler: { directory: { path: './', index: true, listing: true } } }); | ||
server.inject('http://example.com/redirect/directory/subdir', function (res) { | ||
server.inject('http://example.com/redirect/directory/subdir', (res) => { | ||
@@ -599,8 +601,8 @@ expect(res.statusCode).to.equal(200); | ||
it('ignores unused path params', function (done) { | ||
it('ignores unused path params', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/{ignore}/4/{path*}', handler: { directory: { path: './' } } }); | ||
server.inject('/crap/4/file.js', function (res) { | ||
server.inject('/crap/4/file.js', (res) => { | ||
@@ -613,8 +615,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns error when failing to prepare file response due to bad state', function (done) { | ||
it('returns error when failing to prepare file response due to bad state', (done) => { | ||
var server = provisionServer(null, false); | ||
const server = provisionServer(null, false); | ||
server.route({ method: 'GET', path: '/directory/{path*}', handler: { directory: { path: './' } } }); | ||
server.ext('onRequest', function (request, reply) { | ||
server.ext('onRequest', (request, reply) => { | ||
@@ -625,3 +627,3 @@ reply.state('bad', {}); | ||
server.inject('/directory/file.js', function (res) { | ||
server.inject('/directory/file.js', (res) => { | ||
@@ -633,9 +635,9 @@ expect(res.statusCode).to.equal(500); | ||
it('returns error when listing fails due to directory read error', { parallel: false }, function (done) { | ||
it('returns error when listing fails due to directory read error', { parallel: false }, (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directorylist/{path*}', handler: { directory: { path: '../', listing: true } } }); | ||
var orig = Fs.readdir; | ||
Fs.readdir = function (path, callback) { | ||
const orig = Fs.readdir; | ||
Fs.readdir = (path, callback) => { | ||
@@ -646,3 +648,3 @@ Fs.readdir = orig; | ||
server.inject('/directorylist/', function (res) { | ||
server.inject('/directorylist/', (res) => { | ||
@@ -654,8 +656,8 @@ expect(res.statusCode).to.equal(500); | ||
it('appends default extension', function (done) { | ||
it('appends default extension', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directory/{path*}', handler: { directory: { path: __dirname, defaultExtension: 'html' } } }); | ||
server.inject('/directory/directory/index', function (res) { | ||
server.inject('/directory/directory/index', (res) => { | ||
@@ -667,8 +669,8 @@ expect(res.statusCode).to.equal(200); | ||
it('appends default extension when resource ends with /', function (done) { | ||
it('appends default extension when resource ends with /', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directory/{path*}', handler: { directory: { path: __dirname, defaultExtension: 'html' } } }); | ||
server.inject('/directory/directory/index/', function (res) { | ||
server.inject('/directory/directory/index/', (res) => { | ||
@@ -680,8 +682,8 @@ expect(res.statusCode).to.equal(200); | ||
it('appends default extension and fails to find file', function (done) { | ||
it('appends default extension and fails to find file', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directory/{path*}', handler: { directory: { path: __dirname, defaultExtension: 'html' } } }); | ||
server.inject('/directory/directory/none', function (res) { | ||
server.inject('/directory/directory/none', (res) => { | ||
@@ -693,8 +695,8 @@ expect(res.statusCode).to.equal(404); | ||
it('does not append default extension when directory exists', function (done) { | ||
it('does not append default extension when directory exists', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directory/{path*}', handler: { directory: { path: __dirname, defaultExtension: 'html' } } }); | ||
server.inject('/directory/directory', function (res) { | ||
server.inject('/directory/directory', (res) => { | ||
@@ -706,5 +708,5 @@ expect(res.statusCode).to.equal(302); | ||
it('resolves path name from plugin using specified path', function (done) { | ||
it('resolves path name from plugin using specified path', (done) => { | ||
var plugin = function (server, options, next) { | ||
const plugin = (server, options, next) => { | ||
@@ -720,6 +722,6 @@ server.path(__dirname); | ||
var server = provisionServer({ router: { stripTrailingSlash: false } }); | ||
server.register({ register: plugin }, {}, function () { }); | ||
const server = provisionServer({ router: { stripTrailingSlash: false } }); | ||
server.register({ register: plugin }, {}, () => { }); | ||
server.inject('/test/index.html', function (res) { | ||
server.inject('/test/index.html', (res) => { | ||
@@ -731,5 +733,5 @@ expect(res.statusCode).to.equal(200); | ||
it('resolves path name from plugin using relative path', function (done) { | ||
it('resolves path name from plugin using relative path', (done) => { | ||
var plugin = function (server, options, next) { | ||
const plugin = (server, options, next) => { | ||
@@ -744,6 +746,6 @@ server.route({ method: 'GET', path: '/test/{path*}', config: { handler: { directory: { path: Path.join('.', 'test', 'directory'), index: false, listing: false } } } }); | ||
var server = provisionServer({ router: { stripTrailingSlash: false } }); | ||
server.register({ register: plugin }, {}, function () { }); | ||
const server = provisionServer({ router: { stripTrailingSlash: false } }); | ||
server.register({ register: plugin }, {}, () => { }); | ||
server.inject('/test/index.html', function (res) { | ||
server.inject('/test/index.html', (res) => { | ||
@@ -755,8 +757,8 @@ expect(res.statusCode).to.equal(200); | ||
it('resolves root pathnames', function (done) { | ||
it('resolves root pathnames', (done) => { | ||
var server = provisionServer({ router: { stripTrailingSlash: false } }); | ||
const server = provisionServer({ router: { stripTrailingSlash: false } }); | ||
server.route({ method: 'GET', path: '/test/{path*}', handler: { directory: { path: Path.join(__dirname, 'directory') } } }); | ||
server.inject('/test/index.html', function (res) { | ||
server.inject('/test/index.html', (res) => { | ||
@@ -768,8 +770,8 @@ expect(res.statusCode).to.equal(200); | ||
it('resolves relative pathnames', function (done) { | ||
it('resolves relative pathnames', (done) => { | ||
var server = provisionServer({ router: { stripTrailingSlash: false } }); | ||
const server = provisionServer({ router: { stripTrailingSlash: false } }); | ||
server.route({ method: 'GET', path: '/test/{path*}', handler: { directory: { path: Path.join('.', 'test', 'directory') } } }); | ||
server.inject('/test/index.html', function (res) { | ||
server.inject('/test/index.html', (res) => { | ||
@@ -781,5 +783,5 @@ expect(res.statusCode).to.equal(200); | ||
it('returns error when path function returns error', function (done) { | ||
it('returns error when path function returns error', (done) => { | ||
var path = function () { | ||
const path = () => { | ||
@@ -789,6 +791,6 @@ return Boom.badRequest('Really?!'); | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/test/{path*}', handler: { directory: { path: path } } }); | ||
server.inject('/test/index.html', function (res) { | ||
server.inject('/test/index.html', (res) => { | ||
@@ -801,5 +803,5 @@ expect(res.statusCode).to.equal(400); | ||
it('returns error when path function returns invalid response', function (done) { | ||
it('returns error when path function returns invalid response', (done) => { | ||
var path = function () { | ||
const path = () => { | ||
@@ -809,6 +811,6 @@ return 5; | ||
var server = provisionServer(null, false); | ||
const server = provisionServer(null, false); | ||
server.route({ method: 'GET', path: '/test/{path*}', handler: { directory: { path: path } } }); | ||
server.inject('/test/index.html', function (res) { | ||
server.inject('/test/index.html', (res) => { | ||
@@ -820,8 +822,8 @@ expect(res.statusCode).to.equal(500); | ||
it('returns a gzipped file using precompressed file', function (done) { | ||
it('returns a gzipped file using precompressed file', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/{p*}', handler: { directory: { path: './file', lookupCompressed: true } } }); | ||
server.inject({ url: '/image.png', headers: { 'accept-encoding': 'gzip' } }, function (res) { | ||
server.inject({ url: '/image.png', headers: { 'accept-encoding': 'gzip' } }, (res) => { | ||
@@ -831,3 +833,3 @@ expect(res.headers['content-type']).to.equal('image/png'); | ||
var content = Fs.readFileSync('./test/file/image.png.gz'); | ||
const content = Fs.readFileSync('./test/file/image.png.gz'); | ||
expect(res.headers['content-length']).to.equal(content.length); | ||
@@ -839,8 +841,8 @@ expect(res.rawPayload.length).to.equal(content.length); | ||
it('respects the etagMethod option', function (done) { | ||
it('respects the etagMethod option', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/{p*}', handler: { directory: { path: './file', etagMethod: 'simple' } } }); | ||
server.inject('/image.png', function (res) { | ||
server.inject('/image.png', (res) => { | ||
@@ -852,8 +854,8 @@ expect(res.headers.etag).to.match(/^".+-.+"$/); | ||
it('returns a 403 when missing file read permission', function (done) { | ||
it('returns a 403 when missing file read permission', (done) => { | ||
var filename = Hoek.uniqueFilename(Os.tmpDir()); | ||
const filename = Hoek.uniqueFilename(Os.tmpDir()); | ||
Fs.writeFileSync(filename, 'data'); | ||
var fd; | ||
let fd; | ||
if (process.platform === 'win32') { | ||
@@ -863,10 +865,11 @@ // make a permissionless file by unlinking an open file | ||
Fs.unlinkSync(filename); | ||
} else { | ||
} | ||
else { | ||
Fs.chmodSync(filename, 0); | ||
} | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/test/{path*}', handler: { directory: { path: Path.dirname(filename) } } }); | ||
server.inject('/test/' + Path.basename(filename), function (res) { | ||
server.inject('/test/' + Path.basename(filename), (res) => { | ||
@@ -876,3 +879,4 @@ // cleanup | ||
Fs.closeSync(fd); | ||
} else { | ||
} | ||
else { | ||
Fs.unlinkSync(filename); | ||
@@ -886,16 +890,16 @@ } | ||
it('returns error when a file open fails', function (done) { | ||
it('returns error when a file open fails', (done) => { | ||
var orig = Fs.open; | ||
const orig = Fs.open; | ||
Fs.open = function () { // can return EMFILE error | ||
Fs.open = orig; | ||
var callback = arguments[arguments.length - 1]; | ||
const callback = arguments[arguments.length - 1]; | ||
callback(new Error('failed')); | ||
}; | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/test/{path*}', handler: { directory: { path: './' } } }); | ||
server.inject('/test/fail', function (res) { | ||
server.inject('/test/fail', (res) => { | ||
@@ -907,8 +911,8 @@ expect(res.statusCode).to.equal(500); | ||
it('returns a 404 for null byte paths', function (done) { | ||
it('returns a 404 for null byte paths', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/{path*}', handler: { directory: { path: './' } } }); | ||
server.inject('/index%00.html', function (res) { | ||
server.inject('/index%00.html', (res) => { | ||
@@ -920,6 +924,6 @@ expect(res.statusCode).to.equal(404); | ||
it('only stats the file system once when requesting a file', function (done) { | ||
it('only stats the file system once when requesting a file', (done) => { | ||
var orig = Fs.fstat; | ||
var callCnt = 0; | ||
const orig = Fs.fstat; | ||
let callCnt = 0; | ||
Fs.fstat = function () { | ||
@@ -931,6 +935,6 @@ | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/directory/{path*}', handler: { directory: { path: './' } } }); | ||
server.inject('/directory/directory.js', function (res) { | ||
server.inject('/directory/directory.js', (res) => { | ||
@@ -937,0 +941,0 @@ Fs.fstat = orig; |
722
test/file.js
@@ -0,14 +1,16 @@ | ||
'use strict'; | ||
// Load modules | ||
var ChildProcess = require('child_process'); | ||
var Fs = require('fs'); | ||
var Os = require('os'); | ||
var Path = require('path'); | ||
var Boom = require('boom'); | ||
var Code = require('code'); | ||
var Hapi = require('hapi'); | ||
var Hoek = require('hoek'); | ||
var Items = require('items'); | ||
var Inert = require('..'); | ||
var Lab = require('lab'); | ||
const ChildProcess = require('child_process'); | ||
const Fs = require('fs'); | ||
const Os = require('os'); | ||
const Path = require('path'); | ||
const Boom = require('boom'); | ||
const Code = require('code'); | ||
const Hapi = require('hapi'); | ||
const Hoek = require('hoek'); | ||
const Items = require('items'); | ||
const Inert = require('..'); | ||
const Lab = require('lab'); | ||
@@ -18,3 +20,3 @@ | ||
var internals = {}; | ||
const internals = {}; | ||
@@ -24,15 +26,15 @@ | ||
var lab = exports.lab = Lab.script(); | ||
var describe = lab.describe; | ||
var it = lab.it; | ||
var expect = Code.expect; | ||
const lab = exports.lab = Lab.script(); | ||
const describe = lab.describe; | ||
const it = lab.it; | ||
const expect = Code.expect; | ||
describe('file', function () { | ||
describe('file', () => { | ||
describe('handler()', function () { | ||
describe('handler()', () => { | ||
var provisionServer = function (connection, etagsCacheMaxSize) { | ||
const provisionServer = (connection, etagsCacheMaxSize) => { | ||
var server = new Hapi.Server(); | ||
const server = new Hapi.Server(); | ||
server.connection(connection || {}); | ||
@@ -43,8 +45,8 @@ server.register(etagsCacheMaxSize !== undefined ? { register: Inert, options: { etagsCacheMaxSize: etagsCacheMaxSize } } : Inert, Hoek.ignore); | ||
it('returns a file in the response with the correct headers', function (done) { | ||
it('returns a file in the response with the correct headers', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
var handler = function (request, reply) { | ||
const server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
const handler = (request, reply) => { | ||
reply.file('../package.json').code(499); | ||
reply.file('package.json', { confine: '../' }).code(499); | ||
}; | ||
@@ -54,3 +56,3 @@ | ||
server.inject('/file', function (res) { | ||
server.inject('/file', (res) => { | ||
@@ -66,8 +68,8 @@ expect(res.statusCode).to.equal(499); | ||
it('returns a file using route relativeTo', function (done) { | ||
it('returns a file using route relativeTo', (done) => { | ||
var server = provisionServer(); | ||
var handler = function (request, reply) { | ||
const server = provisionServer(); | ||
const handler = (request, reply) => { | ||
reply.file('../package.json'); | ||
reply.file('../package.json', { confine: false }); | ||
}; | ||
@@ -77,3 +79,3 @@ | ||
server.inject('/file', function (res) { | ||
server.inject('/file', (res) => { | ||
@@ -86,8 +88,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a file in the response with the correct headers using cwd relative paths without content-disposition header', function (done) { | ||
it('returns a file in the response with the correct headers using cwd relative paths without content-disposition header', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/', handler: { file: './package.json' } }); | ||
server.inject('/', function (res) { | ||
server.inject('/', (res) => { | ||
@@ -103,8 +105,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a file in the response with the inline content-disposition header when using route config', function (done) { | ||
it('returns a file in the response with the inline content-disposition header when using route config', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: './' } } }); | ||
const server = provisionServer({ routes: { files: { relativeTo: './' } } }); | ||
server.route({ method: 'GET', path: '/', handler: { file: { path: './package.json', mode: 'inline' } } }); | ||
server.inject('/', function (res) { | ||
server.inject('/', (res) => { | ||
@@ -120,8 +122,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a file in the response with the inline content-disposition header when using route config and overriding filename', function (done) { | ||
it('returns a file in the response with the inline content-disposition header when using route config and overriding filename', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: './' } } }); | ||
const server = provisionServer({ routes: { files: { relativeTo: './' } } }); | ||
server.route({ method: 'GET', path: '/', handler: { file: { path: './package.json', mode: 'inline', filename: 'attachment.json' } } }); | ||
server.inject('/', function (res) { | ||
server.inject('/', (res) => { | ||
@@ -137,8 +139,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a file in the response with the attachment content-disposition header when using route config', function (done) { | ||
it('returns a file in the response with the attachment content-disposition header when using route config', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/', handler: { file: { path: './package.json', mode: 'attachment' } } }); | ||
server.inject('/', function (res) { | ||
server.inject('/', (res) => { | ||
@@ -154,8 +156,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a file in the response with the attachment content-disposition header when using route config and overriding filename', function (done) { | ||
it('returns a file in the response with the attachment content-disposition header when using route config and overriding filename', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/', handler: { file: { path: './package.json', mode: 'attachment', filename: 'attachment.json' } } }); | ||
server.inject('/', function (res) { | ||
server.inject('/', (res) => { | ||
@@ -171,8 +173,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a file in the response without the content-disposition header when using route config mode false', function (done) { | ||
it('returns a file in the response without the content-disposition header when using route config mode false', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/', handler: { file: { path: './package.json', mode: false } } }); | ||
server.inject('/', function (res) { | ||
server.inject('/', (res) => { | ||
@@ -188,8 +190,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a file with correct headers when using attachment mode', function (done) { | ||
it('returns a file with correct headers when using attachment mode', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
var handler = function (request, reply) { | ||
const server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
const handler = (request, reply) => { | ||
reply.file(Path.join(__dirname, '..', 'package.json'), { mode: 'attachment' }); | ||
reply.file(Path.join(__dirname, '..', 'package.json'), { confine: '..', mode: 'attachment' }); | ||
}; | ||
@@ -199,3 +201,3 @@ | ||
server.inject('/file', function (res) { | ||
server.inject('/file', (res) => { | ||
@@ -211,8 +213,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a file with correct headers when using attachment mode and overriding the filename', function (done) { | ||
it('returns a file with correct headers when using attachment mode and overriding the filename', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
var handler = function (request, reply) { | ||
const server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
const handler = (request, reply) => { | ||
reply.file(Path.join(__dirname, '..', 'package.json'), { mode: 'attachment', filename: 'attachment.json' }); | ||
reply.file(Path.join(__dirname, '..', 'package.json'), { confine: '..', mode: 'attachment', filename: 'attachment.json' }); | ||
}; | ||
@@ -222,3 +224,3 @@ | ||
server.inject('/file', function (res) { | ||
server.inject('/file', (res) => { | ||
@@ -234,8 +236,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a file with correct headers when using inline mode', function (done) { | ||
it('returns a file with correct headers when using inline mode', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
var handler = function (request, reply) { | ||
const server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
const handler = (request, reply) => { | ||
reply.file(Path.join(__dirname, '..', 'package.json'), { mode: 'inline' }); | ||
reply.file(Path.join(__dirname, '..', 'package.json'), { confine: '..', mode: 'inline' }); | ||
}; | ||
@@ -245,3 +247,3 @@ | ||
server.inject('/file', function (res) { | ||
server.inject('/file', (res) => { | ||
@@ -257,8 +259,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a file with correct headers when using inline mode and overriding filename', function (done) { | ||
it('returns a file with correct headers when using inline mode and overriding filename', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
var handler = function (request, reply) { | ||
const server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
const handler = (request, reply) => { | ||
reply.file(Path.join(__dirname, '..', 'package.json'), { mode: 'inline', filename: 'attachment.json' }); | ||
reply.file(Path.join(__dirname, '..', 'package.json'), { confine: '..', mode: 'inline', filename: 'attachment.json' }); | ||
}; | ||
@@ -268,3 +270,3 @@ | ||
server.inject('/file', function (res) { | ||
server.inject('/file', (res) => { | ||
@@ -280,9 +282,9 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a 404 when the file is not found', function (done) { | ||
it('returns a 404 when the file is not found', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: '/no/such/path/x1' } } }); | ||
const server = provisionServer({ routes: { files: { relativeTo: '/no/such/path/x1' } } }); | ||
server.route({ method: 'GET', path: '/filenotfound', handler: { file: 'nopes' } }); | ||
server.inject('/filenotfound', function (res) { | ||
server.inject('/filenotfound', (res) => { | ||
@@ -294,9 +296,9 @@ expect(res.statusCode).to.equal(404); | ||
it('returns a 403 when the file is a directory', function (done) { | ||
it('returns a 403 when the file is a directory', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/filefolder', handler: { file: 'lib' } }); | ||
server.inject('/filefolder', function (res) { | ||
server.inject('/filefolder', (res) => { | ||
@@ -308,8 +310,8 @@ expect(res.statusCode).to.equal(403); | ||
it('returns a file using the built-in handler config', function (done) { | ||
it('returns a file using the built-in handler config', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
const server = provisionServer({ routes: { files: { relativeTo: Path.join(__dirname, '..') } } }); | ||
server.route({ method: 'GET', path: '/staticfile', handler: { file: Path.join(__dirname, '..', 'package.json') } }); | ||
server.inject('/staticfile', function (res) { | ||
server.inject('/staticfile', (res) => { | ||
@@ -324,13 +326,13 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a file using the file function with the built-in handler config', function (done) { | ||
it('returns a file using the file function with the built-in handler config', (done) => { | ||
var filenameFn = function (request) { | ||
const filenameFn = (request) => { | ||
return '../lib/' + request.params.file; | ||
return './lib/' + request.params.file; | ||
}; | ||
var server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
const server = provisionServer({ routes: { files: { relativeTo: Path.join(__dirname, '..') } } }); | ||
server.route({ method: 'GET', path: '/filefn/{file}', handler: { file: filenameFn } }); | ||
server.inject('/filefn/index.js', function (res) { | ||
server.inject('/filefn/index.js', (res) => { | ||
@@ -345,8 +347,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a file in the response with the correct headers (relative path)', function (done) { | ||
it('returns a file in the response with the correct headers (relative path)', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: '.' } } }); | ||
var relativeHandler = function (request, reply) { | ||
const server = provisionServer({ routes: { files: { relativeTo: '.' } } }); | ||
const relativeHandler = (request, reply) => { | ||
reply.file('./package.json'); | ||
reply.file('./package.json', { confine: true }); | ||
}; | ||
@@ -356,3 +358,3 @@ | ||
server.inject('/relativefile', function (res) { | ||
server.inject('/relativefile', (res) => { | ||
@@ -367,8 +369,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a file using the built-in handler config (relative path)', function (done) { | ||
it('returns a file using the built-in handler config (relative path)', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
server.route({ method: 'GET', path: '/relativestaticfile', handler: { file: '../package.json' } }); | ||
const server = provisionServer({ routes: { files: { relativeTo: Path.join(__dirname, '..') } } }); | ||
server.route({ method: 'GET', path: '/relativestaticfile', handler: { file: './package.json' } }); | ||
server.inject('/relativestaticfile', function (res) { | ||
server.inject('/relativestaticfile', (res) => { | ||
@@ -383,8 +385,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a file with default mime type', function (done) { | ||
it('returns a file with default mime type', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/', handler: { file: Path.join(__dirname, '..', 'LICENSE') } }); | ||
server.inject('/', function (res) { | ||
server.inject('/', (res) => { | ||
@@ -397,8 +399,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a file in the response with the correct headers using custom mime type', function (done) { | ||
it('returns a file in the response with the correct headers using custom mime type', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
var handler = function (request, reply) { | ||
const server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
const handler = (request, reply) => { | ||
reply.file('../LICENSE').type('application/example'); | ||
reply.file('../LICENSE', { confine: false }).type('application/example'); | ||
}; | ||
@@ -408,3 +410,3 @@ | ||
server.inject('/file', function (res) { | ||
server.inject('/file', (res) => { | ||
@@ -417,10 +419,10 @@ expect(res.statusCode).to.equal(200); | ||
it('handles multiple simultaneous requests', function (done) { | ||
it('handles multiple simultaneous requests', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: Path.join(__dirname, '..', 'package.json') } }); | ||
Items.parallel(['/file', '/file'], function (req, next) { | ||
Items.parallel(['/file', '/file'], (req, next) => { | ||
server.inject(req, function (res) { | ||
server.inject(req, (res) => { | ||
@@ -435,8 +437,8 @@ expect(res.statusCode).to.equal(200); | ||
it('does not cache etags', function (done) { | ||
it('does not cache etags', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: __dirname } } }, 0); | ||
const server = provisionServer({ routes: { files: { relativeTo: __dirname } } }, 0); | ||
server.route({ method: 'GET', path: '/note', handler: { file: './file/note.txt' } }); | ||
server.inject('/note', function (res) { | ||
server.inject('/note', (res) => { | ||
@@ -447,3 +449,3 @@ expect(res.statusCode).to.equal(200); | ||
server.inject('/note', function (res2) { | ||
server.inject('/note', (res2) => { | ||
@@ -458,8 +460,8 @@ expect(res2.statusCode).to.equal(200); | ||
it('does not return etag when etagMethod is false', function (done) { | ||
it('does not return etag when etagMethod is false', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: __dirname } } }, 0); | ||
const server = provisionServer({ routes: { files: { relativeTo: __dirname } } }, 0); | ||
server.route({ method: 'GET', path: '/note', handler: { file: { path: './file/note.txt', etagMethod: false } } }); | ||
server.inject('/note', function (res) { | ||
server.inject('/note', (res) => { | ||
@@ -470,3 +472,3 @@ expect(res.statusCode).to.equal(200); | ||
server.inject('/note', function (res2) { | ||
server.inject('/note', (res2) => { | ||
@@ -481,5 +483,5 @@ expect(res2.statusCode).to.equal(200); | ||
it('invalidates etags when file changes (simple)', function (done) { | ||
it('invalidates etags when file changes (simple)', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
const server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
@@ -490,3 +492,3 @@ server.route({ method: 'GET', path: '/note', handler: { file: { path: './file/note.txt', etagMethod: 'simple' } } }); | ||
server.inject('/note', function (res1) { | ||
server.inject('/note', (res1) => { | ||
@@ -497,3 +499,3 @@ expect(res1.statusCode).to.equal(200); | ||
var etag1 = res1.headers.etag; | ||
const etag1 = res1.headers.etag; | ||
@@ -505,3 +507,3 @@ expect(etag1.slice(0, 1)).to.equal('"'); | ||
server.inject({ url: '/note', headers: { 'if-none-match': etag1 } }, function (res2) { | ||
server.inject({ url: '/note', headers: { 'if-none-match': etag1 } }, (res2) => { | ||
@@ -513,3 +515,3 @@ expect(res2.statusCode).to.equal(304); | ||
var fd1 = Fs.openSync(Path.join(__dirname, 'file', 'note.txt'), 'w'); | ||
const fd1 = Fs.openSync(Path.join(__dirname, 'file', 'note.txt'), 'w'); | ||
Fs.writeSync(fd1, new Buffer('Test'), 0, 4); | ||
@@ -520,3 +522,3 @@ Fs.closeSync(fd1); | ||
server.inject({ url: '/note', headers: { 'if-none-match': etag1 } }, function (res3) { | ||
server.inject({ url: '/note', headers: { 'if-none-match': etag1 } }, (res3) => { | ||
@@ -527,6 +529,6 @@ expect(res3.statusCode).to.equal(200); | ||
var etag2 = res3.headers.etag; | ||
const etag2 = res3.headers.etag; | ||
expect(etag1).to.not.equal(etag2); | ||
var fd2 = Fs.openSync(Path.join(__dirname, 'file', 'note.txt'), 'w'); | ||
const fd2 = Fs.openSync(Path.join(__dirname, 'file', 'note.txt'), 'w'); | ||
Fs.writeSync(fd2, new Buffer('Test1'), 0, 5); | ||
@@ -537,3 +539,3 @@ Fs.closeSync(fd2); | ||
server.inject({ url: '/note', headers: { 'if-none-match': etag2 } }, function (res4) { | ||
server.inject({ url: '/note', headers: { 'if-none-match': etag2 } }, (res4) => { | ||
@@ -544,7 +546,7 @@ expect(res4.statusCode).to.equal(200); | ||
var etag3 = res4.headers.etag; | ||
const etag3 = res4.headers.etag; | ||
expect(etag1).to.not.equal(etag3); | ||
expect(etag2).to.not.equal(etag3); | ||
var fd3 = Fs.openSync(Path.join(__dirname, 'file', 'note.txt'), 'w'); | ||
const fd3 = Fs.openSync(Path.join(__dirname, 'file', 'note.txt'), 'w'); | ||
Fs.writeSync(fd3, new Buffer('Test'), 0, 4); | ||
@@ -560,5 +562,5 @@ Fs.closeSync(fd3); | ||
it('invalidates etags when file changes (hash)', function (done) { | ||
it('invalidates etags when file changes (hash)', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
const server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
@@ -569,3 +571,3 @@ server.route({ method: 'GET', path: '/note', handler: { file: './file/note.txt' } }); | ||
server.inject('/note', function (res1) { | ||
server.inject('/note', (res1) => { | ||
@@ -576,3 +578,3 @@ expect(res1.statusCode).to.equal(200); | ||
var etag1 = res1.headers.etag; | ||
const etag1 = res1.headers.etag; | ||
@@ -584,3 +586,3 @@ expect(etag1.slice(0, 1)).to.equal('"'); | ||
server.inject({ url: '/note', headers: { 'if-none-match': etag1 } }, function (res2) { | ||
server.inject({ url: '/note', headers: { 'if-none-match': etag1 } }, (res2) => { | ||
@@ -593,3 +595,3 @@ expect(res2.statusCode).to.equal(304); | ||
Fs.unlinkSync(Path.join(__dirname, 'file', 'note.txt')); | ||
var fd1 = Fs.openSync(Path.join(__dirname, 'file', 'note.txt'), 'w'); | ||
const fd1 = Fs.openSync(Path.join(__dirname, 'file', 'note.txt'), 'w'); | ||
Fs.writeSync(fd1, new Buffer('Test'), 0, 4); | ||
@@ -600,3 +602,3 @@ Fs.closeSync(fd1); | ||
server.inject('/note', function (res3) { | ||
server.inject('/note', (res3) => { | ||
@@ -607,6 +609,6 @@ expect(res3.statusCode).to.equal(200); | ||
var etag2 = res3.headers.etag; | ||
const etag2 = res3.headers.etag; | ||
expect(etag1).to.equal(etag2); | ||
var fd2 = Fs.openSync(Path.join(__dirname, 'file', 'note.txt'), 'w'); | ||
const fd2 = Fs.openSync(Path.join(__dirname, 'file', 'note.txt'), 'w'); | ||
Fs.writeSync(fd2, new Buffer('Test1'), 0, 5); | ||
@@ -617,3 +619,3 @@ Fs.closeSync(fd2); | ||
server.inject({ url: '/note', headers: { 'if-none-match': etag2 } }, function (res4) { | ||
server.inject({ url: '/note', headers: { 'if-none-match': etag2 } }, (res4) => { | ||
@@ -624,6 +626,6 @@ expect(res4.statusCode).to.equal(200); | ||
var etag3 = res4.headers.etag; | ||
const etag3 = res4.headers.etag; | ||
expect(etag1).to.not.equal(etag3); | ||
var fd3 = Fs.openSync(Path.join(__dirname, 'file', 'note.txt'), 'w'); | ||
const fd3 = Fs.openSync(Path.join(__dirname, 'file', 'note.txt'), 'w'); | ||
Fs.writeSync(fd3, new Buffer('Test'), 0, 4); | ||
@@ -634,3 +636,3 @@ Fs.closeSync(fd3); | ||
server.inject('/note', function (res5) { | ||
server.inject('/note', (res5) => { | ||
@@ -641,3 +643,3 @@ expect(res5.statusCode).to.equal(200); | ||
var etag4 = res5.headers.etag; | ||
const etag4 = res5.headers.etag; | ||
expect(etag1).to.equal(etag4); | ||
@@ -653,11 +655,11 @@ | ||
it('returns a 304 when the request has if-modified-since and the response has not been modified since (larger)', function (done) { | ||
it('returns a 304 when the request has if-modified-since and the response has not been modified since (larger)', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: Path.join(__dirname, '..', 'package.json') } }); | ||
server.inject('/file', function (res1) { | ||
server.inject('/file', (res1) => { | ||
var last = new Date(Date.parse(res1.headers['last-modified']) + 1000); | ||
server.inject({ url: '/file', headers: { 'if-modified-since': last.toUTCString() } }, function (res2) { | ||
const last = new Date(Date.parse(res1.headers['last-modified']) + 1000); | ||
server.inject({ url: '/file', headers: { 'if-modified-since': last.toUTCString() } }, (res2) => { | ||
@@ -673,10 +675,10 @@ expect(res2.statusCode).to.equal(304); | ||
it('returns a 304 when the request has if-modified-since and the response has not been modified since (equal)', function (done) { | ||
it('returns a 304 when the request has if-modified-since and the response has not been modified since (equal)', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: Path.join(__dirname, '..', 'package.json') } }); | ||
server.inject('/file', function (res1) { | ||
server.inject('/file', (res1) => { | ||
server.inject({ url: '/file', headers: { 'if-modified-since': res1.headers['last-modified'] } }, function (res2) { | ||
server.inject({ url: '/file', headers: { 'if-modified-since': res1.headers['last-modified'] } }, (res2) => { | ||
@@ -692,9 +694,9 @@ expect(res2.statusCode).to.equal(304); | ||
it('computes etag header for 304 response', function (done) { | ||
it('computes etag header for 304 response', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: Path.join(__dirname, '..', 'package.json') } }); | ||
var future = new Date(Date.now() + 1000); | ||
server.inject({ url: '/file', headers: { 'if-modified-since': future } }, function (res) { | ||
const future = new Date(Date.now() + 1000); | ||
server.inject({ url: '/file', headers: { 'if-modified-since': future } }, (res) => { | ||
@@ -708,8 +710,8 @@ expect(res.statusCode).to.equal(304); | ||
it('computes etag header for head response', function (done) { | ||
it('computes etag header for head response', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: Path.join(__dirname, '..', 'package.json') } }); | ||
server.inject({ method: 'HEAD', url: '/file' }, function (res) { | ||
server.inject({ method: 'HEAD', url: '/file' }, (res) => { | ||
@@ -723,8 +725,8 @@ expect(res.statusCode).to.equal(200); | ||
it('changes etag when content encoding is used', function (done) { | ||
it('changes etag when content encoding is used', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: Path.join(__dirname, '..', 'package.json') } }); | ||
server.inject('/file', function (res1) { | ||
server.inject('/file', (res1) => { | ||
@@ -735,3 +737,3 @@ expect(res1.statusCode).to.equal(200); | ||
server.inject({ url: '/file', headers: { 'accept-encoding': 'gzip' } }, function (res2) { | ||
server.inject({ url: '/file', headers: { 'accept-encoding': 'gzip' } }, (res2) => { | ||
@@ -748,5 +750,5 @@ expect(res2.statusCode).to.equal(200); | ||
it('return a 500 on hashing errors', function (done) { | ||
it('return a 500 on hashing errors', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: Path.join(__dirname, '..', 'package.json') } }); | ||
@@ -756,3 +758,3 @@ | ||
var orig = Fs.createReadStream; | ||
const orig = Fs.createReadStream; | ||
Fs.createReadStream = function (path, options) { | ||
@@ -762,3 +764,3 @@ | ||
process.nextTick(function () { | ||
process.nextTick(() => { | ||
@@ -771,3 +773,3 @@ Fs.closeSync(options.fd); | ||
server.inject('/file', function (res) { | ||
server.inject('/file', (res) => { | ||
@@ -779,5 +781,5 @@ expect(res.statusCode).to.equal(500); | ||
it('handles multiple simultaneous request hashing errors', function (done) { | ||
it('handles multiple simultaneous request hashing errors', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: Path.join(__dirname, '..', 'package.json') } }); | ||
@@ -787,3 +789,3 @@ | ||
var orig = Fs.createReadStream; | ||
const orig = Fs.createReadStream; | ||
Fs.createReadStream = function (path, options) { | ||
@@ -793,3 +795,3 @@ | ||
process.nextTick(function () { | ||
process.nextTick(() => { | ||
@@ -802,7 +804,7 @@ Fs.closeSync(options.fd); | ||
Items.parallel(['/file', '/file'], function (req, next) { | ||
Items.parallel(['/file', '/file'], (req, next) => { | ||
setImmediate(function () { | ||
setImmediate(() => { | ||
server.inject(req, function (res) { | ||
server.inject(req, (res) => { | ||
@@ -816,8 +818,8 @@ expect(res.statusCode).to.equal(500); | ||
it('returns valid http date responses in last-modified header', function (done) { | ||
it('returns valid http date responses in last-modified header', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: Path.join(__dirname, '..', 'package.json') } }); | ||
server.inject('/file', function (res) { | ||
server.inject('/file', (res) => { | ||
@@ -830,8 +832,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns 200 if if-modified-since is invalid', function (done) { | ||
it('returns 200 if if-modified-since is invalid', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: Path.join(__dirname, '..', 'package.json') } }); | ||
server.inject({ url: '/file', headers: { 'if-modified-since': 'some crap' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'if-modified-since': 'some crap' } }, (res) => { | ||
@@ -843,9 +845,9 @@ expect(res.statusCode).to.equal(200); | ||
it('returns 200 if last-modified is invalid', function (done) { | ||
it('returns 200 if last-modified is invalid', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ | ||
method: 'GET', | ||
path: '/', | ||
handler: function (request, reply) { | ||
handler: (request, reply) => { | ||
@@ -856,3 +858,3 @@ reply('ok').header('last-modified', 'some crap'); | ||
server.inject({ url: '/', headers: { 'if-modified-since': 'Fri, 28 Mar 2014 22:52:39 GMT' } }, function (res2) { | ||
server.inject({ url: '/', headers: { 'if-modified-since': 'Fri, 28 Mar 2014 22:52:39 GMT' } }, (res2) => { | ||
@@ -864,15 +866,15 @@ expect(res2.statusCode).to.equal(200); | ||
it('closes file handlers when not reading file stream', { skip: process.platform === 'win32' }, function (done) { | ||
it('closes file handlers when not reading file stream', { skip: process.platform === 'win32' }, (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: Path.join(__dirname, '..', 'package.json') } }); | ||
server.inject('/file', function (res1) { | ||
server.inject('/file', (res1) => { | ||
server.inject({ url: '/file', headers: { 'if-modified-since': res1.headers.date } }, function (res2) { | ||
server.inject({ url: '/file', headers: { 'if-modified-since': res1.headers.date } }, (res2) => { | ||
expect(res2.statusCode).to.equal(304); | ||
var cmd = ChildProcess.spawn('lsof', ['-p', process.pid]); | ||
var lsof = ''; | ||
cmd.stdout.on('data', function (buffer) { | ||
const cmd = ChildProcess.spawn('lsof', ['-p', process.pid]); | ||
let lsof = ''; | ||
cmd.stdout.on('data', (buffer) => { | ||
@@ -882,7 +884,7 @@ lsof += buffer.toString(); | ||
cmd.stdout.on('end', function () { | ||
cmd.stdout.on('end', () => { | ||
var count = 0; | ||
var lines = lsof.split('\n'); | ||
for (var i = 0, il = lines.length; i < il; ++i) { | ||
let count = 0; | ||
const lines = lsof.split('\n'); | ||
for (let i = 0; i < lines.length; ++i) { | ||
count += !!lines[i].match(/package.json/); | ||
@@ -900,9 +902,9 @@ } | ||
it('closes file handlers when not using a manually open file stream', { skip: process.platform === 'win32' }, function (done) { | ||
it('closes file handlers when not using a manually open file stream', { skip: process.platform === 'win32' }, (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ | ||
method: 'GET', | ||
path: '/file', | ||
handler: function (request, reply) { | ||
handler: (request, reply) => { | ||
@@ -913,10 +915,10 @@ reply(Fs.createReadStream(Path.join(__dirname, '..', 'package.json'))).header('etag', 'abc'); | ||
server.inject('/file', function (res1) { | ||
server.inject('/file', (res1) => { | ||
server.inject({ url: '/file', headers: { 'if-none-match': res1.headers.etag } }, function (res2) { | ||
server.inject({ url: '/file', headers: { 'if-none-match': res1.headers.etag } }, (res2) => { | ||
expect(res2.statusCode).to.equal(304); | ||
var cmd = ChildProcess.spawn('lsof', ['-p', process.pid]); | ||
var lsof = ''; | ||
cmd.stdout.on('data', function (buffer) { | ||
const cmd = ChildProcess.spawn('lsof', ['-p', process.pid]); | ||
let lsof = ''; | ||
cmd.stdout.on('data', (buffer) => { | ||
@@ -926,7 +928,7 @@ lsof += buffer.toString(); | ||
cmd.stdout.on('end', function () { | ||
cmd.stdout.on('end', () => { | ||
var count = 0; | ||
var lines = lsof.split('\n'); | ||
for (var i = 0, il = lines.length; i < il; ++i) { | ||
let count = 0; | ||
const lines = lsof.split('\n'); | ||
for (let i = 0; i < lines.length; ++i) { | ||
count += !!lines[i].match(/package.json/); | ||
@@ -944,8 +946,8 @@ } | ||
it('returns a gzipped file in the response when the request accepts gzip', function (done) { | ||
it('returns a gzipped file in the response when the request accepts gzip', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
var handler = function (request, reply) { | ||
const server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
const handler = (request, reply) => { | ||
reply.file(Path.join(__dirname, '..', 'package.json')); | ||
reply.file(Path.join(__dirname, '..', 'package.json'), { confine: '..' }); | ||
}; | ||
@@ -955,3 +957,3 @@ | ||
server.inject({ url: '/file', headers: { 'accept-encoding': 'gzip' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'accept-encoding': 'gzip' } }, (res) => { | ||
@@ -967,6 +969,6 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a plain file when not compressible', function (done) { | ||
it('returns a plain file when not compressible', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
var handler = function (request, reply) { | ||
const server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
const handler = (request, reply) => { | ||
@@ -978,3 +980,3 @@ reply.file(Path.join(__dirname, 'file', 'image.png')); | ||
server.inject({ url: '/file', headers: { 'accept-encoding': 'gzip' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'accept-encoding': 'gzip' } }, (res) => { | ||
@@ -990,8 +992,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a deflated file in the response when the request accepts deflate', function (done) { | ||
it('returns a deflated file in the response when the request accepts deflate', (done) => { | ||
var server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
var handler = function (request, reply) { | ||
const server = provisionServer({ routes: { files: { relativeTo: __dirname } } }); | ||
const handler = (request, reply) => { | ||
reply.file(Path.join(__dirname, '..', 'package.json')); | ||
reply.file(Path.join(__dirname, '..', 'package.json'), { confine: '..' }); | ||
}; | ||
@@ -1001,3 +1003,3 @@ | ||
server.inject({ url: '/file', headers: { 'accept-encoding': 'deflate' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'accept-encoding': 'deflate' } }, (res) => { | ||
@@ -1013,10 +1015,10 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a gzipped file using precompressed file', function (done) { | ||
it('returns a gzipped file using precompressed file', (done) => { | ||
var content = Fs.readFileSync('./test/file/image.png.gz'); | ||
const content = Fs.readFileSync('./test/file/image.png.gz'); | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: './test/file/image.png', lookupCompressed: true } } }); | ||
server.inject({ url: '/file', headers: { 'accept-encoding': 'gzip' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'accept-encoding': 'gzip' } }, (res) => { | ||
@@ -1032,8 +1034,8 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a gzipped file when precompressed file not found', function (done) { | ||
it('returns a gzipped file when precompressed file not found', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: './test/file/note.txt', lookupCompressed: true } } }); | ||
server.inject({ url: '/file', headers: { 'accept-encoding': 'gzip' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'accept-encoding': 'gzip' } }, (res) => { | ||
@@ -1048,10 +1050,10 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a 304 when using precompressed file and if-modified-since set', function (done) { | ||
it('returns a 304 when using precompressed file and if-modified-since set', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: './test/file/image.png', lookupCompressed: true } } }); | ||
server.inject('/file', function (res1) { | ||
server.inject('/file', (res1) => { | ||
server.inject({ url: '/file', headers: { 'if-modified-since': res1.headers.date, 'accept-encoding': 'gzip' } }, function (res2) { | ||
server.inject({ url: '/file', headers: { 'if-modified-since': res1.headers.date, 'accept-encoding': 'gzip' } }, (res2) => { | ||
@@ -1064,8 +1066,8 @@ expect(res2.statusCode).to.equal(304); | ||
it('ignores precompressed file when content-encoding not requested', function (done) { | ||
it('ignores precompressed file when content-encoding not requested', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: './test/file/image.png', lookupCompressed: true } } }); | ||
server.inject('/file', function (res) { | ||
server.inject('/file', (res) => { | ||
@@ -1080,8 +1082,8 @@ expect(res.statusCode).to.equal(200); | ||
it('ignores precompressed file when connection compression is disabled', function (done) { | ||
it('ignores precompressed file when connection compression is disabled', (done) => { | ||
var server = provisionServer({ compression: false }); | ||
const server = provisionServer({ compression: false }); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: './test/file/image.png', lookupCompressed: true } } }); | ||
server.inject({ url: '/file', headers: { 'accept-encoding': 'gzip' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'accept-encoding': 'gzip' } }, (res) => { | ||
@@ -1096,9 +1098,9 @@ expect(res.statusCode).to.equal(200); | ||
it('does not throw an error when adding a route with a parameter and function path', function (done) { | ||
it('does not throw an error when adding a route with a parameter and function path', (done) => { | ||
var fn = function () { | ||
const fn = () => { | ||
var server = provisionServer(); | ||
server.route({ method: 'GET', path: '/fileparam/{path}', handler: { file: function () { } } }); | ||
server.route({ method: 'GET', path: '/filepathparam/{path}', handler: { file: { path: function () { } } } }); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/fileparam/{path}', handler: { file: () => { } } }); | ||
server.route({ method: 'GET', path: '/filepathparam/{path}', handler: { file: { path: () => { } } } }); | ||
}; | ||
@@ -1110,10 +1112,10 @@ | ||
it('responds correctly when file is removed while processing', function (done) { | ||
it('responds correctly when file is removed while processing', (done) => { | ||
var filename = Hoek.uniqueFilename(Os.tmpDir()) + '.package.json'; | ||
const filename = Hoek.uniqueFilename(Os.tmpDir()) + '.package.json'; | ||
Fs.writeFileSync(filename, 'data'); | ||
var server = provisionServer(); | ||
server.route({ method: 'GET', path: '/', handler: { file: filename } }); | ||
server.ext('onPreResponse', function (request, reply) { | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/', handler: { file: { path: filename, confine: false } } }); | ||
server.ext('onPreResponse', (request, reply) => { | ||
@@ -1124,3 +1126,3 @@ Fs.unlinkSync(filename); | ||
server.inject('/', function (res) { | ||
server.inject('/', (res) => { | ||
@@ -1132,12 +1134,12 @@ expect(res.statusCode).to.equal(200); | ||
it('responds correctly when file is changed while processing', function (done) { | ||
it('responds correctly when file is changed while processing', (done) => { | ||
var filename = Hoek.uniqueFilename(Os.tmpDir()) + '.package.json'; | ||
const filename = Hoek.uniqueFilename(Os.tmpDir()) + '.package.json'; | ||
Fs.writeFileSync(filename, 'data'); | ||
var server = provisionServer(); | ||
server.route({ method: 'GET', path: '/', handler: { file: filename } }); | ||
server.ext('onPreResponse', function (request, reply) { | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/', handler: { file: { path: filename, confine: false } } }); | ||
server.ext('onPreResponse', (request, reply) => { | ||
var tempfile = filename + '~'; | ||
const tempfile = filename + '~'; | ||
if (process.platform === 'win32') { | ||
@@ -1148,3 +1150,4 @@ // workaround to replace open file without a permission error | ||
Fs.unlinkSync(tempfile); | ||
} else { | ||
} | ||
else { | ||
// atomic file replace | ||
@@ -1158,3 +1161,3 @@ Fs.writeFileSync(tempfile, 'database'); | ||
server.inject('/', function (res) { | ||
server.inject('/', (res) => { | ||
@@ -1170,12 +1173,12 @@ Fs.unlinkSync(filename); | ||
it('does not marshal response on 304', function (done) { | ||
it('does not marshal response on 304', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: Path.join(__dirname, '..', 'package.json') } }); | ||
server.inject('/file', function (res1) { | ||
server.inject('/file', (res1) => { | ||
server.ext('onPreResponse', function (request, reply) { | ||
server.ext('onPreResponse', (request, reply) => { | ||
request.response._marshall = function () { | ||
request.response._marshall = () => { | ||
@@ -1188,3 +1191,3 @@ throw new Error('not called'); | ||
server.inject({ url: '/file', headers: { 'if-modified-since': res1.headers.date } }, function (res2) { | ||
server.inject({ url: '/file', headers: { 'if-modified-since': res1.headers.date } }, (res2) => { | ||
@@ -1197,10 +1200,10 @@ expect(res2.statusCode).to.equal(304); | ||
it('returns error when aborted while processing', function (done) { | ||
it('returns error when aborted while processing', (done) => { | ||
var filename = Hoek.uniqueFilename(Os.tmpDir()) + '.package.json'; | ||
const filename = Hoek.uniqueFilename(Os.tmpDir()) + '.package.json'; | ||
Fs.writeFileSync(filename, 'data'); | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/', handler: { file: filename } }); | ||
server.ext('onPreResponse', function (request, reply) { | ||
server.ext('onPreResponse', (request, reply) => { | ||
@@ -1210,3 +1213,3 @@ reply(Boom.internal('crapping out')); | ||
server.inject('/', function (res) { | ||
server.inject('/', (res) => { | ||
@@ -1218,8 +1221,8 @@ expect(res.statusCode).to.equal(500); | ||
it('returns error when stat fails unexpectedly', function (done) { | ||
it('returns error when stat fails unexpectedly', (done) => { | ||
var filename = Hoek.uniqueFilename(Os.tmpDir()) + '.package.json'; | ||
const filename = Hoek.uniqueFilename(Os.tmpDir()) + '.package.json'; | ||
Fs.writeFileSync(filename, 'data'); | ||
var orig = Fs.fstat; | ||
const orig = Fs.fstat; | ||
Fs.fstat = function (fd, callback) { // can return EIO error | ||
@@ -1232,6 +1235,6 @@ | ||
var server = provisionServer(); | ||
server.route({ method: 'GET', path: '/', handler: { file: filename } }); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/', handler: { file: { path: filename, confine: false } } }); | ||
server.inject('/', function (res) { | ||
server.inject('/', (res) => { | ||
@@ -1243,19 +1246,19 @@ expect(res.statusCode).to.equal(500); | ||
it('returns error when open fails unexpectedly', function (done) { | ||
it('returns error when open fails unexpectedly', (done) => { | ||
var filename = Hoek.uniqueFilename(Os.tmpDir()) + '.package.json'; | ||
const filename = Hoek.uniqueFilename(Os.tmpDir()) + '.package.json'; | ||
Fs.writeFileSync(filename, 'data'); | ||
var orig = Fs.open; | ||
const orig = Fs.open; | ||
Fs.open = function () { // can return EMFILE error | ||
Fs.open = orig; | ||
var callback = arguments[arguments.length - 1]; | ||
const callback = arguments[arguments.length - 1]; | ||
callback(new Error('failed')); | ||
}; | ||
var server = provisionServer(); | ||
server.route({ method: 'GET', path: '/', handler: { file: filename } }); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/', handler: { file: { path: filename, confine: false } } }); | ||
server.inject('/', function (res) { | ||
server.inject('/', (res) => { | ||
@@ -1267,8 +1270,8 @@ expect(res.statusCode).to.equal(500); | ||
it('returns a 403 when missing file read permission', function (done) { | ||
it('returns a 403 when missing file read permission', (done) => { | ||
var filename = Hoek.uniqueFilename(Os.tmpDir()) + '.package.json'; | ||
const filename = Hoek.uniqueFilename(Os.tmpDir()) + '.package.json'; | ||
Fs.writeFileSync(filename, 'data'); | ||
var retainedFd; | ||
let retainedFd; | ||
if (process.platform === 'win32') { | ||
@@ -1278,16 +1281,17 @@ // make a permissionless file by unlinking an open file | ||
Fs.unlinkSync(filename); | ||
} else { | ||
} | ||
else { | ||
Fs.chmodSync(filename, 0); | ||
} | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/', handler: { file: filename } }); | ||
server.inject('/', function (res1) { | ||
server.inject('/', (res1) => { | ||
var orig = Fs.open; | ||
const orig = Fs.open; | ||
Fs.open = function (path, mode, callback) { // fake alternate permission error | ||
Fs.open = orig; | ||
return Fs.open(path, mode, function (err, fd) { | ||
return Fs.open(path, mode, (err, fd) => { | ||
@@ -1298,3 +1302,4 @@ if (err) { | ||
err.errno = -1; | ||
} else if (err.code === 'EPERM') { | ||
} | ||
else if (err.code === 'EPERM') { | ||
err.code = 'EACCES'; | ||
@@ -1309,3 +1314,3 @@ err.errno = -13; | ||
server.inject('/', function (res2) { | ||
server.inject('/', (res2) => { | ||
@@ -1315,3 +1320,4 @@ // cleanup | ||
Fs.closeSync(retainedFd); | ||
} else { | ||
} | ||
else { | ||
Fs.unlinkSync(filename); | ||
@@ -1327,10 +1333,10 @@ } | ||
describe('response range', function () { | ||
describe('response range', () => { | ||
it('returns a subset of a file (start)', function (done) { | ||
it('returns a subset of a file (start)', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: Path.join(__dirname, 'file/image.png') } } }); | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=0-4' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=0-4' } }, (res) => { | ||
@@ -1346,8 +1352,8 @@ expect(res.statusCode).to.equal(206); | ||
it('returns a subset of a file (middle)', function (done) { | ||
it('returns a subset of a file (middle)', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: Path.join(__dirname, 'file/image.png') } } }); | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=1-5' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=1-5' } }, (res) => { | ||
@@ -1363,8 +1369,8 @@ expect(res.statusCode).to.equal(206); | ||
it('returns a subset of a file (-to)', function (done) { | ||
it('returns a subset of a file (-to)', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: Path.join(__dirname, 'file/image.png') } } }); | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=-5' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=-5' } }, (res) => { | ||
@@ -1380,8 +1386,8 @@ expect(res.statusCode).to.equal(206); | ||
it('returns a subset of a file (from-)', function (done) { | ||
it('returns a subset of a file (from-)', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: Path.join(__dirname, 'file/image.png') } } }); | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=42005-' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=42005-' } }, (res) => { | ||
@@ -1397,8 +1403,8 @@ expect(res.statusCode).to.equal(206); | ||
it('returns a subset of a file (beyond end)', function (done) { | ||
it('returns a subset of a file (beyond end)', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: Path.join(__dirname, 'file/image.png') } } }); | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=42005-42011' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=42005-42011' } }, (res) => { | ||
@@ -1414,10 +1420,10 @@ expect(res.statusCode).to.equal(206); | ||
it('returns a subset of a file (if-range)', function (done) { | ||
it('returns a subset of a file (if-range)', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: Path.join(__dirname, 'file/image.png') } } }); | ||
server.inject('/file', function (res1) { | ||
server.inject('/file', (res1) => { | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=42005-42011', 'if-range': res1.headers.etag } }, function (res2) { | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=42005-42011', 'if-range': res1.headers.etag } }, (res2) => { | ||
@@ -1434,8 +1440,8 @@ expect(res2.statusCode).to.equal(206); | ||
it('returns 200 on incorrect if-range', function (done) { | ||
it('returns 200 on incorrect if-range', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: Path.join(__dirname, 'file/image.png') } } }); | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=42005-42011', 'if-range': 'abc' } }, function (res2) { | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=42005-42011', 'if-range': 'abc' } }, (res2) => { | ||
@@ -1447,8 +1453,8 @@ expect(res2.statusCode).to.equal(200); | ||
it('returns 416 on invalid range (unit)', function (done) { | ||
it('returns 416 on invalid range (unit)', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: Path.join(__dirname, 'file/image.png') } } }); | ||
server.inject({ url: '/file', headers: { 'range': 'horses=1-5' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'range': 'horses=1-5' } }, (res) => { | ||
@@ -1461,8 +1467,8 @@ expect(res.statusCode).to.equal(416); | ||
it('returns 416 on invalid range (inversed)', function (done) { | ||
it('returns 416 on invalid range (inversed)', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: Path.join(__dirname, 'file/image.png') } } }); | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=5-1' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=5-1' } }, (res) => { | ||
@@ -1475,8 +1481,8 @@ expect(res.statusCode).to.equal(416); | ||
it('returns 416 on invalid range (format)', function (done) { | ||
it('returns 416 on invalid range (format)', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: Path.join(__dirname, 'file/image.png') } } }); | ||
server.inject({ url: '/file', headers: { 'range': 'bytes 1-5' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'range': 'bytes 1-5' } }, (res) => { | ||
@@ -1489,8 +1495,8 @@ expect(res.statusCode).to.equal(416); | ||
it('returns 416 on invalid range (empty range)', function (done) { | ||
it('returns 416 on invalid range (empty range)', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: Path.join(__dirname, 'file/image.png') } } }); | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=-' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=-' } }, (res) => { | ||
@@ -1503,8 +1509,8 @@ expect(res.statusCode).to.equal(416); | ||
it('returns 200 on multiple ranges', function (done) { | ||
it('returns 200 on multiple ranges', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: Path.join(__dirname, 'file/image.png') } } }); | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=1-5,7-10' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=1-5,7-10' } }, (res) => { | ||
@@ -1517,5 +1523,5 @@ expect(res.statusCode).to.equal(200); | ||
it('reads partial file content for a non-compressible file', function (done) { | ||
it('reads partial file content for a non-compressible file', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: Path.join(__dirname, 'file/image.png'), etagMethod: false } } }); | ||
@@ -1525,4 +1531,4 @@ | ||
var createOptions; | ||
var orig = Fs.createReadStream; | ||
let createOptions; | ||
const orig = Fs.createReadStream; | ||
Fs.createReadStream = function (path, options) { | ||
@@ -1536,3 +1542,3 @@ | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=1-4', 'accept-encoding': 'gzip' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=1-4', 'accept-encoding': 'gzip' } }, (res) => { | ||
@@ -1549,8 +1555,8 @@ expect(res.statusCode).to.equal(206); | ||
it('returns 200 when content-length is missing', function (done) { | ||
it('returns 200 when content-length is missing', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: Path.join(__dirname, 'file/image.png') } } }); | ||
server.ext('onPreResponse', function (request, reply) { | ||
server.ext('onPreResponse', (request, reply) => { | ||
@@ -1561,3 +1567,3 @@ delete request.response.headers['content-length']; | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=1-5' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=1-5' } }, (res) => { | ||
@@ -1570,7 +1576,7 @@ expect(res.statusCode).to.equal(200); | ||
it('returns 200 for dynamically compressed responses', function (done) { | ||
it('returns 200 for dynamically compressed responses', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: Path.join(__dirname, 'file/note.txt'), lookupCompressed: false } } }); | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=1-3', 'accept-encoding': 'gzip' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=1-3', 'accept-encoding': 'gzip' } }, (res) => { | ||
@@ -1586,7 +1592,7 @@ expect(res.statusCode).to.equal(200); | ||
it('returns a subset of a file when compression is disabled', function (done) { | ||
it('returns a subset of a file when compression is disabled', (done) => { | ||
var server = provisionServer({ compression: false }); | ||
const server = provisionServer({ compression: false }); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: Path.join(__dirname, 'file/note.txt'), lookupCompressed: false } } }); | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=1-3', 'accept-encoding': 'gzip' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=1-3', 'accept-encoding': 'gzip' } }, (res) => { | ||
@@ -1601,7 +1607,7 @@ expect(res.statusCode).to.equal(206); | ||
it('returns a subset of a file using precompressed file', function (done) { | ||
it('returns a subset of a file using precompressed file', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: Path.join(__dirname, 'file/image.png'), lookupCompressed: true } } }); | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=10-18', 'accept-encoding': 'gzip' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=10-18', 'accept-encoding': 'gzip' } }, (res) => { | ||
@@ -1618,7 +1624,7 @@ expect(res.statusCode).to.equal(206); | ||
it('returns a subset for dynamically compressed responses with "identity" encoding', function (done) { | ||
it('returns a subset for dynamically compressed responses with "identity" encoding', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: Path.join(__dirname, 'file/note.txt'), lookupCompressed: false } } }); | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=1-3', 'accept-encoding': 'identity' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=1-3', 'accept-encoding': 'identity' } }, (res) => { | ||
@@ -1633,8 +1639,8 @@ expect(res.statusCode).to.equal(206); | ||
it('returns a subset when content-type is missing', function (done) { | ||
it('returns a subset when content-type is missing', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { path: Path.join(__dirname, 'file/note.txt') } } }); | ||
server.ext('onPreResponse', function (request, reply) { | ||
server.ext('onPreResponse', (request, reply) => { | ||
@@ -1645,3 +1651,3 @@ delete request.response.headers['content-type']; | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=1-5' } }, function (res) { | ||
server.inject({ url: '/file', headers: { 'range': 'bytes=1-5' } }, (res) => { | ||
@@ -1658,8 +1664,8 @@ expect(res.statusCode).to.equal(206); | ||
it('has not leaked file descriptors', { skip: process.platform === 'win32' }, function (done) { | ||
it('has not leaked file descriptors', { skip: process.platform === 'win32' }, (done) => { | ||
// validate that all descriptors has been closed | ||
var cmd = ChildProcess.spawn('lsof', ['-p', process.pid]); | ||
var lsof = ''; | ||
cmd.stdout.on('data', function (buffer) { | ||
const cmd = ChildProcess.spawn('lsof', ['-p', process.pid]); | ||
let lsof = ''; | ||
cmd.stdout.on('data', (buffer) => { | ||
@@ -1669,7 +1675,7 @@ lsof += buffer.toString(); | ||
cmd.stdout.on('end', function () { | ||
cmd.stdout.on('end', () => { | ||
var count = 0; | ||
var lines = lsof.split('\n'); | ||
for (var i = 0, il = lines.length; i < il; ++i) { | ||
let count = 0; | ||
const lines = lsof.split('\n'); | ||
for (let i = 0; i < lines.length; ++i) { | ||
count += !!lines[i].match(/package.json/); | ||
@@ -1676,0 +1682,0 @@ } |
@@ -0,8 +1,11 @@ | ||
'use strict'; | ||
// Load modules | ||
var Code = require('code'); | ||
var Hapi = require('hapi'); | ||
var Hoek = require('hoek'); | ||
var Inert = require('..'); | ||
var Lab = require('lab'); | ||
const Code = require('code'); | ||
const Hapi = require('hapi'); | ||
const Hoek = require('hoek'); | ||
const Inert = require('..'); | ||
const Lab = require('lab'); | ||
const Path = require('path'); | ||
@@ -12,3 +15,3 @@ | ||
var internals = {}; | ||
const internals = {}; | ||
@@ -18,13 +21,13 @@ | ||
var lab = exports.lab = Lab.script(); | ||
var describe = lab.describe; | ||
var it = lab.it; | ||
var expect = Code.expect; | ||
const lab = exports.lab = Lab.script(); | ||
const describe = lab.describe; | ||
const it = lab.it; | ||
const expect = Code.expect; | ||
describe('security', function () { | ||
describe('security', () => { | ||
var provisionServer = function () { | ||
const provisionServer = () => { | ||
var server = new Hapi.Server(); | ||
const server = new Hapi.Server(); | ||
server.connection({ routes: { files: { relativeTo: __dirname } } }); | ||
@@ -35,10 +38,10 @@ server.register(Inert, Hoek.ignore); | ||
it('blocks path traversal to files outside of hosted directory is not allowed with null byte injection', function (done) { | ||
it('blocks path traversal to files outside of hosted directory is not allowed with null byte injection', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/{path*}', handler: { directory: { path: './directory' } } }); | ||
server.inject('/%00/../security.js', function (res) { | ||
server.inject('/%00/../security.js', (res) => { | ||
expect(res.statusCode).to.equal(403); | ||
expect(res.statusCode).to.equal(404); | ||
done(); | ||
@@ -48,8 +51,8 @@ }); | ||
it('blocks path traversal to files outside of hosted directory is not allowed', function (done) { | ||
it('blocks path traversal to files outside of hosted directory is not allowed', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/{path*}', handler: { directory: { path: './directory' } } }); | ||
server.inject('/../security.js', function (res) { | ||
server.inject('/../security.js', (res) => { | ||
@@ -61,8 +64,8 @@ expect(res.statusCode).to.equal(403); | ||
it('blocks path traversal to files outside of hosted directory is not allowed with encoded slash', function (done) { | ||
it('blocks path traversal to files outside of hosted directory is not allowed with encoded slash', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/{path*}', handler: { directory: { path: './directory' } } }); | ||
server.inject('/..%2Fsecurity.js', function (res) { | ||
server.inject('/..%2Fsecurity.js', (res) => { | ||
@@ -74,10 +77,10 @@ expect(res.statusCode).to.equal(403); | ||
it('blocks path traversal to files outside of hosted directory is not allowed with double encoded slash', function (done) { | ||
it('blocks path traversal to files outside of hosted directory is not allowed with double encoded slash', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/{path*}', handler: { directory: { path: './directory' } } }); | ||
server.inject('/..%252Fsecurity.js', function (res) { | ||
server.inject('/..%252Fsecurity.js', (res) => { | ||
expect(res.statusCode).to.equal(403); | ||
expect(res.statusCode).to.equal(404); | ||
done(); | ||
@@ -87,10 +90,10 @@ }); | ||
it('blocks path traversal to files outside of hosted directory is not allowed with unicode encoded slash', function (done) { | ||
it('blocks path traversal to files outside of hosted directory is not allowed with unicode encoded slash', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/{path*}', handler: { directory: { path: './directory' } } }); | ||
server.inject('/..\u2216security.js', function (res) { | ||
server.inject('/..\u2216security.js', (res) => { | ||
expect(res.statusCode).to.equal(403); | ||
expect(res.statusCode).to.equal(404); | ||
done(); | ||
@@ -100,8 +103,8 @@ }); | ||
it('blocks null byte injection when serving a file', function (done) { | ||
it('blocks null byte injection when serving a file', (done) => { | ||
var server = provisionServer(); | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/{path*}', handler: { directory: { path: './directory' } } }); | ||
server.inject('/index%00.html', function (res) { | ||
server.inject('/index%00.html', (res) => { | ||
@@ -112,2 +115,67 @@ expect(res.statusCode).to.equal(404); | ||
}); | ||
it('blocks access to files outside of base directory for file handler', (done) => { | ||
const server = provisionServer(); | ||
const secureHandler = { file: { confine: './directory', path: Path.join(__dirname, 'security.js') } }; | ||
server.route({ method: 'GET', path: '/secure', handler: secureHandler }); | ||
server.route({ method: 'GET', path: '/open', handler: Hoek.applyToDefaults(secureHandler, { file: { confine: false } }) }); | ||
server.inject('/secure', (res1) => { | ||
expect(res1.statusCode).to.equal(403); | ||
server.inject('/open', (res2) => { | ||
expect(res2.statusCode).to.equal(200); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('blocks path traversal to files outside of base directory for file handler', (done) => { | ||
const server = provisionServer(); | ||
server.route({ method: 'GET', path: '/file', handler: { file: { confine: './directory', path: '../security.js' } } }); | ||
server.inject('/file', (res) => { | ||
expect(res.statusCode).to.equal(403); | ||
done(); | ||
}); | ||
}); | ||
it('blocks access to files outside of base directory for reply.file()', (done) => { | ||
const server = provisionServer(); | ||
const fileHandler = (request, reply) => { | ||
reply.file(Path.join(__dirname, 'security.js'), { confine: Path.join(__dirname, 'directory') }); | ||
}; | ||
server.route({ method: 'GET', path: '/file', handler: fileHandler }); | ||
server.inject('/file', (res) => { | ||
expect(res.statusCode).to.equal(403); | ||
done(); | ||
}); | ||
}); | ||
it('blocks path traversal to files outside of base directory for reply.file()', (done) => { | ||
const server = provisionServer(); | ||
const fileHandler = (request, reply) => { | ||
reply.file('../security.js', { confine: Path.join(__dirname, 'directory') }); | ||
}; | ||
server.route({ method: 'GET', path: '/file', handler: fileHandler }); | ||
server.inject('/file', (res) => { | ||
expect(res.statusCode).to.equal(403); | ||
done(); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
398760
2300
252
+ Addedammo@2.1.2(transitive)
+ Addedboom@3.2.25.3.3(transitive)
+ Addedhoek@4.3.1(transitive)
+ Addedisemail@2.2.1(transitive)
+ Addeditems@2.2.1(transitive)
+ Addedjoi@8.4.2(transitive)
+ Addedlru-cache@4.0.2(transitive)
+ Addedpseudomap@1.0.2(transitive)
+ Addedtopo@2.1.1(transitive)
+ Addedyallist@2.1.2(transitive)
- Removedammo@1.0.1(transitive)
- Removedboom@2.10.1(transitive)
- Removedhoek@2.16.3(transitive)
- Removedisemail@1.2.0(transitive)
- Removeditems@1.1.1(transitive)
- Removedjoi@6.10.1(transitive)
- Removedlru-cache@2.7.3(transitive)
- Removedtopo@1.1.0(transitive)
Updatedammo@2.x.x
Updatedboom@3.x.x
Updatedhoek@4.x.x
Updateditems@2.x.x
Updatedjoi@8.x.x
Updatedlru-cache@4.0.x