UNPKG

express-http2

Version:

Fast, unopinionated, minimalist web framework

144 lines (115 loc) 2.95 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = createSendFile; var _utils = require('./utils'); var _send = require('send'); var _send2 = _interopRequireDefault(_send); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function createSendFile(_ref) { var req = _ref.req; var res = _ref.res; return function (path, options, callback) { var done = callback; var next = req.next; var opts = options || {}; if (!path) { throw new TypeError('path argument is required to res.sendFile'); } // support function as second arg if (typeof options === 'function') { done = options; opts = {}; } if (!opts.root && !(0, _utils.isAbsolute)(path)) { throw new TypeError('path must be absolute or specify root to res.sendFile'); } // create file stream var pathname = encodeURI(path); var file = (0, _send2.default)(req, pathname, opts); // transfer sendfile(res, file, opts, function (err) { if (done) return done(err); if (err && err.code === 'EISDIR') return next(); // next() all but write errors if (err && err.code !== 'ECONNABORTED' && err.syscall !== 'write') { next(err); } }); }; } function sendfile(res, file, options, callback) { var done = false; var streaming; // request aborted function onaborted() { if (done) return; done = true; var err = new Error('Request aborted'); err.code = 'ECONNABORTED'; callback(err); } // directory function ondirectory() { if (done) return; done = true; var err = new Error('EISDIR, read'); err.code = 'EISDIR'; callback(err); } // errors function onerror(err) { if (done) return; done = true; callback(err); } // ended function onend() { if (done) return; done = true; callback(); } // file function onfile() { streaming = false; } // finished function onfinish(err) { if (err && err.code === 'ECONNRESET') return onaborted(); if (err) return onerror(err); if (done) return; setImmediate(function () { if (streaming !== false && !done) { onaborted(); return; } if (done) return; done = true; callback(); }); } // streaming function onstream() { streaming = true; } file.on('directory', ondirectory); file.on('end', onend); file.on('error', onerror); file.on('file', onfile); file.on('stream', onstream); onFinished(res, onfinish); if (options.headers) { // set headers on successful transfer file.on('headers', function headers(res) { var obj = options.headers; var keys = Object.keys(obj); for (var i = 0; i < keys.length; i++) { var k = keys[i]; res.setHeader(k, obj[k]); } }); } // pipe file.pipe(res); }