expressjs / expressjs/serve-static
Extensions vs Directory
- Dominant language
- JavaScript
- Stars
- 1.4k
- Forks
- 241
- PR merge metrics
- No merged PRs in 30d
Description
When we have a directory named like a file, extensions should win over redirect. Let's assume this listing:
```
/news.html
/news/latest.html
/news/index.html
```
and we set the `extensions` options to `['html']`.
Right now `/news` is redirected to `/news/` and serves `/news/index.html`
But it should serve `/news.html` – only if that file is missing, it should redirect to the directory. Whereas `/news/` should always go for the directory (index).
I achieved this by changing the `sendFile` method like follows, but there are probably better ways to achieve the same.
```javascript
SendStream.prototype.sendFile = function sendFile (path) {
var i = 0
var self = this
var onExtensionsFailed
debug('stat "%s"', path)
fs.stat(path, function onstat (err, stat) {
if (err && err.code === 'ENOENT' && !extname(path) && path[path.length - 1] !== sep) {
// not found, check extensions
return next(err)
}
if (err) return self.onStatError(err)
if (stat.isDirectory()) {
onExtensionsFailed = function() {
self.redirect(path)
}
if (self._extensions.length > 0 && path[path.length - 1] !== sep) {
return next()
} else {
return self.redirect(path)
}
}
self.emit('file', path, stat)
self.send(path, stat)
})
function next (err) {
if (self._extensions.length <= i) {
if (onExtensionsFailed) {
return onExtensionsFailed()
}
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)
})
}
}
```
Does this make sense? (I am by the way trying to achieve the same kind of handling like Netlify does when serving static files).
Contributor guide
Assessment
This issue has not been assessed yet.