Skip to content

Commit

Permalink
Add extensions option
Browse files Browse the repository at this point in the history
closes #51
  • Loading branch information
jacekkopecky authored and dougwilson committed Aug 6, 2014
1 parent c7a90d4 commit c2c76f1
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 11 deletions.
5 changes: 5 additions & 0 deletions History.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
unreleased
==========

* Add `extensions` option

0.7.4 / 2014-08-04
==================

Expand Down
6 changes: 6 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ var app = http.createServer(function(req, res){
- `'deny'` Send a 403 for any request for a dotfile.
- `'ignore'` Pretend like the dotfile does not exist and 404.

#### extensions

If a given file doesn't exist, try appending one of the given extensions,
in the given order. By default, this is disabled (set to `false`). An
example value that will serve extension-less HTML files: `['html', 'htm']`.

#### index

By default send supports "index.html" files, to disable this
Expand Down
60 changes: 49 additions & 11 deletions lib/send.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,12 @@ function SendStream(req, path, options) {
this._dotfiles = undefined
}

this._extensions = options.extensions !== undefined
? normalizeList(options.extensions)
: []

this._index = options.index !== undefined
? normalizeIndex(options.index)
? normalizeList(options.index)
: ['index.html']

this._maxage = options.maxAge || options.maxage
Expand Down Expand Up @@ -169,7 +173,7 @@ SendStream.prototype.hidden = deprecate.function(function hidden(val) {
*/

SendStream.prototype.index = deprecate.function(function index(paths) {
var index = !paths ? [] : normalizeIndex(paths);
var index = !paths ? [] : normalizeList(paths);
debug('index %o', paths);
this._index = index;
return this;
Expand Down Expand Up @@ -459,14 +463,7 @@ SendStream.prototype.pipe = function(res){
return res;
}

debug('stat "%s"', path);
fs.stat(path, function(err, stat){
if (err) return self.onStatError(err);
if (stat.isDirectory()) return self.redirect(self.path);
self.emit('file', path, stat);
self.send(path, stat);
});

this.sendFile(path);
return res;
};

Expand Down Expand Up @@ -557,6 +554,47 @@ SendStream.prototype.send = function(path, stat){
this.stream(path, options);
};

/**
* Transfer file for `path`.
*
* @param {String} path
* @api private
*/
SendStream.prototype.sendFile = function sendFile(path) {
var i = 0
var self = this

debug('stat "%s"', path);
fs.stat(path, function onstat(err, stat) {
if (err && err.code === 'ENOENT' && path[path.length - 1] !== sep) {
// not found, check extensions
return next(err)
}
if (err) return self.onStatError(err)
if (stat.isDirectory()) return self.redirect(self.path)
self.emit('file', path, stat)
self.send(path, stat)
})

function next(err) {
if (self._extensions.length <= i) {
return err
? self.onStatError(err)
: self.error(404)
}

var p = path + '.' + self._extensions[i++]

debug('stat "%s"', p)
fs.stat(p, function (err, stat) {
if (err) return next(err)
if (stat.isDirectory()) return next()
self.emit('file', p, stat)
self.send(p, stat)
})
}
}

/**
* Transfer index for `path`.
*
Expand Down Expand Up @@ -705,6 +743,6 @@ function containsDotFile(parts) {
* @api private
*/

function normalizeIndex(val){
function normalizeList(val){
return [].concat(val || [])
}
1 change: 1 addition & 0 deletions test/fixtures/name.dir/name.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tobi
1 change: 1 addition & 0 deletions test/fixtures/name.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>tobi</p>
50 changes: 50 additions & 0 deletions test/send.js
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,56 @@ describe('send(file, options)', function(){
})
})

describe('extensions', function () {
it('should be not be enabled by default', function (done) {
var server = createServer({root: fixtures});

request(server)
.get('/tobi')
.expect(404, done)
})

it('should be configurable', function (done) {
var server = createServer({extensions: 'txt', root: fixtures})

request(server)
.get('/name')
.expect(200, 'tobi', done)
})

it('should support disabling extensions', function (done) {
var server = createServer({extensions: false, root: fixtures})

request(server)
.get('/name')
.expect(404, done)
})

it('should support fallbacks', function (done) {
var server = createServer({extensions: ['htm', 'html', 'txt'], root: fixtures})

request(server)
.get('/name')
.expect(200, '<p>tobi</p>', done)
})

it('should 404 if nothing found', function (done) {
var server = createServer({extensions: ['htm', 'html', 'txt'], root: fixtures})

request(server)
.get('/bob')
.expect(404, done)
})

it('should skip directories', function (done) {
var server = createServer({extensions: ['file', 'dir'], root: fixtures})

request(server)
.get('/name')
.expect(404, done)
})
})

describe('from', function(){
it('should set with deprecated from', function(done){
var app = http.createServer(function(req, res){
Expand Down

0 comments on commit c2c76f1

Please sign in to comment.