diff --git a/README.md b/README.md index 4167926..0516be0 100644 --- a/README.md +++ b/README.md @@ -81,9 +81,14 @@ This is skipped if the requested file already has an extension. ##### index -By default send supports "index.html" files, to disable this -set `false` or to supply a new index pass a string or an array -in preferred order. +By default *send* supports "index.html" files. To disable this, set index option +to `false`, or you can be able to supply a new index passing a string with the +filename or an array in the preferred order. + +Alternatively, you can pass a function that will generate the index. The +function will receive the filesystem absolute path and will have the +`SendStream` instance as `this` object. You should call internally to the +`this.send()` method or try to mimic its behaviour. ##### lastModified @@ -229,7 +234,7 @@ var app = http.createServer(function onRequest (req, res) { }).listen(3000) ``` -## License +## License [MIT](LICENSE) diff --git a/index.js b/index.js index 81ec0b3..bf4c170 100644 --- a/index.js +++ b/index.js @@ -142,13 +142,20 @@ function SendStream (req, path, options) { this._dotfiles = undefined } - this._extensions = opts.extensions !== undefined - ? normalizeList(opts.extensions, 'extensions option') - : [] + this._extensions = normalizeList(opts.extensions, 'extensions option') - this._index = opts.index !== undefined - ? normalizeList(opts.index, 'index option') - : ['index.html'] + switch (typeof opts.index) { + case 'function': + this._index = opts.index + break + + case 'undefined': + this._index = ['index.html'] + break + + default: + this._index = normalizeList(opts.index, 'index option') + } this._lastModified = opts.lastModified !== undefined ? Boolean(opts.lastModified) @@ -542,11 +549,16 @@ SendStream.prototype.pipe = function pipe (res) { } // index file support + if (typeof this._index === 'function') { + this._index(path) + return res + } if (this._index.length && this.path[this.path.length - 1] === '/') { this.sendIndex(path) return res } + // Render a file, or an index as a file this.sendFile(path) return res } @@ -703,6 +715,11 @@ SendStream.prototype.sendFile = function sendFile (path) { * @api private */ SendStream.prototype.sendIndex = function sendIndex (path) { + if (listenerCount(this, 'index')) { + this.emit('index', path) + return + } + var i = -1 var self = this diff --git a/test/send.js b/test/send.js index da101aa..213530d 100644 --- a/test/send.js +++ b/test/send.js @@ -702,9 +702,11 @@ describe('send(file).pipe(res)', function () { .pipe(res) }) + var filePath = path.join(fixtures, 'pets', 'index.html') + request(app) .get('/pets/') - .expect(200, fs.readFileSync(path.join(fixtures, 'pets', 'index.html'), 'utf8'), done) + .expect(200, fs.readFileSync(filePath, 'utf8'), done) }) }) @@ -1115,6 +1117,41 @@ describe('send(file, options)', function () { .expect(200, '

tobi

', done) }) + it('should support function', function (done) { + function index (path) { + var res = this.res + + res.end('

tobi

') + } + + var app = http.createServer(function (req, res) { + send(req, req.url, {root: fixtures}) + .on('index', index) + .pipe(res) + }) + + request(app) + .get('/') + .expect(200, '

tobi

', done) + }) + + it('should support function as option', function (done) { + function index (path) { + var res = this.res + + res.end('

tobi

') + } + + var app = http.createServer(function (req, res) { + send(req, req.url, {root: fixtures, index: index}) + .pipe(res) + }) + + request(app) + .get('/') + .expect(200, '

tobi

', done) + }) + it('should support disabling', function (done) { request(createServer({root: fixtures, index: false})) .get('/pets/')