Stat parent directory when necessary

This commit is contained in:
Douglas Christopher Wilson
2015-06-14 22:29:58 -04:00
parent 6d3160a32c
commit 420d159be7
4 changed files with 37 additions and 10 deletions

View File

@@ -2,6 +2,7 @@ unreleased
==========
* Send non-chunked response for `OPTIONS`
* Stat parent directory when necessary
* Use `Date.prototype.toLocaleDateString` to format date
* deps: accepts@~1.2.9
- deps: mime-types@~2.1.1

View File

@@ -171,21 +171,21 @@ function serveIndex(root, options) {
*/
serveIndex.html = function _html(req, res, files, next, dir, showUp, icons, path, view, template, stylesheet) {
fs.readFile(template, 'utf8', function(err, str){
if (showUp) {
files.unshift('..');
}
stat(path, files, function (err, stats) {
if (err) return next(err);
fs.readFile(stylesheet, 'utf8', function(err, style){
fs.readFile(template, 'utf8', function(err, str){
if (err) return next(err);
stat(path, files, function(err, stats){
fs.readFile(stylesheet, 'utf8', function(err, style){
if (err) return next(err);
var fileData = files.map(function (file, i) {
return { name: file, stat: stats[i] };
}).sort(fileSort);
if (showUp) {
fileData.unshift({ name: '..' });
}
var body = str
.replace(/\{style\}/g, style.concat(iconStyle(fileData, icons)))
.replace(/\{files\}/g, createHtmlFileList(fileData, dir, icons, view))
@@ -243,7 +243,7 @@ function createHtmlFileList(files, dir, useIcons, view) {
html += files.map(function (file) {
var classes = [];
var isDir = '..' == file.name || (file.stat && file.stat.isDirectory());
var isDir = file.stat && file.stat.isDirectory();
var path = dir.split('/').map(function (c) { return encodeURIComponent(c); });
if (useIcons) {
@@ -293,6 +293,12 @@ function createHtmlFileList(files, dir, useIcons, view) {
*/
function fileSort(a, b) {
// sort ".." to the top
if (a.name === '..' || b.name === '..') {
return a.name === b.name ? 0
: a.name === '..' ? -1 : 1;
}
return Number(b.stat && b.stat.isDirectory()) - Number(a.stat && a.stat.isDirectory()) ||
String(a.name).toLocaleLowerCase().localeCompare(String(b.name).toLocaleLowerCase());
}
@@ -393,7 +399,7 @@ function iconStyle (files, useIcons) {
for (i = 0; i < files.length; i++) {
var file = files[i];
var isDir = '..' == file.name || (file.stat && file.stat.isDirectory());
var isDir = file.stat && file.stat.isDirectory();
var icon = isDir
? { className: 'icon-directory', fileName: icons.folder }
: iconLookup(file.name);

1
test/fixtures/users/#dir/tobi.txt vendored Normal file
View File

@@ -0,0 +1 @@
ferret

View File

@@ -270,7 +270,7 @@ describe('serveIndex(root)', function () {
});
it('should filter directory paths', function (done) {
var cb = after(3, done)
var cb = after(4, done)
var server = createServer(fixtures, {'filter': filter})
function filter(name, index, list, dir) {
@@ -451,6 +451,25 @@ describe('serveIndex(root)', function () {
.end(done);
});
it('should include link to parent directory', function (done) {
var server = createServer()
request(server)
.get('/users')
.end(function (err, res) {
if (err) return done(err);
var body = res.text.split('</h1>')[1];
var urls = body.split(/<a href="([^"]*)"/).filter(function(s, i){ return i%2; });
assert.deepEqual(urls, [
'/',
'/users/%23dir',
'/users/index.html',
'/users/tobi.txt'
]);
done();
});
});
it('should work for directory with #', function (done) {
var server = createServer()