UNPKG

inert

Version:

Static file and directory handlers plugin for hapi.js

115 lines (76 loc) 2.46 kB
'use strict'; const Fs = require('fs'); const Util = require('util'); const Boom = require('boom'); const Bounce = require('bounce'); const Hoek = require('hoek'); const internals = { methods: { promised: ['open', 'close', 'fstat', 'readdir'], raw: ['createReadStream'] } }; exports.File = function (path) { this.path = path; this.fd = null; }; exports.File.prototype.open = async function (mode) { Hoek.assert(this.fd === null); try { this.fd = await exports.open(this.path, mode); } catch (err) { const data = { path: this.path }; if (this.path.indexOf('\u0000') !== -1 || err.code === 'ENOENT') { throw Boom.notFound(null, data); } if (err.code === 'EACCES' || err.code === 'EPERM') { data.code = err.code; throw Boom.forbidden(null, data); } throw Boom.boomify(err, { message: 'Failed to open file', data }); } }; exports.File.prototype.close = function () { if (this.fd !== null) { Bounce.background(exports.close(this.fd)); this.fd = null; } }; exports.File.prototype.stat = async function () { Hoek.assert(this.fd !== null); try { const stat = await exports.fstat(this.fd); if (stat.isDirectory()) { throw Boom.forbidden(null, { code: 'EISDIR', path: this.path }); } return stat; } catch (err) { this.close(this.fd); Bounce.rethrow(err, ['boom', 'system']); throw Boom.boomify(err, { message: 'Failed to stat file', data: { path: this.path } }); } }; exports.File.prototype.openStat = async function (mode) { await this.open(mode); return this.stat(); }; exports.File.prototype.createReadStream = function (options) { Hoek.assert(this.fd !== null); options = Object.assign({ fd: this.fd, start: 0 }, options); const stream = exports.createReadStream(this.path, options); if (options.autoClose !== false) { this.fd = null; // The stream now owns the fd } return stream; }; // Export Fs methods for (let i = 0; i < internals.methods.raw.length; ++i) { const method = internals.methods.raw[i]; exports[method] = Fs[method].bind(Fs); } for (let i = 0; i < internals.methods.promised.length; ++i) { const method = internals.methods.promised[i]; exports[method] = Util.promisify(Fs[method]); }