Skip to content

Commit b525b4a

Browse files
Feat/--dir-overrides-404 flag (#894)
* feat: add 'dir-overrides-404' flag * tests: add tests * docs: update documentation --------- Co-authored-by: Eric Dubé <[email protected]>
1 parent cf063f0 commit b525b4a

File tree

12 files changed

+101
-1
lines changed

12 files changed

+101
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ with the provided Dockerfile.
6464
|`-a` |Address to use |0.0.0.0|
6565
|`--base-dir` | Base path to serve files from | `/` |
6666
|`-d` |Show directory listings |`true` |
67+
|`-dir-overrides-404` | Whether `-d` should override magic `404.html` | `false`
6768
|`-i` | Display autoIndex | `true` |
6869
|`-g` or `--gzip` |When enabled it will serve `./public/some-file.js.gz` in place of `./public/some-file.js` when a gzipped version of the file exists and the request accepts gzip encoding. If brotli is also enabled, it will try to serve brotli first.|`false`|
6970
|`-b` or `--brotli`|When enabled it will serve `./public/some-file.js.br` in place of `./public/some-file.js` when a brotli compressed version of the file exists and the request accepts `br` encoding. If gzip is also enabled, it will try to serve brotli first. |`false`|

bin/http-server

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ if (argv.h || argv.help) {
3030
' -p --port Port to use. If 0, look for open port. [8080]',
3131
' -a Address to use [0.0.0.0] or [::]',
3232
' -d Show directory listings [true]',
33+
' --dir-overrides-404 Whether -d should override magic 404.html [false]',
3334
' --base-dir Base directory to serve files from [/]',
3435
' -i Display autoIndex [true]',
3536
' -g --gzip Serve gzip files when possible [false]',
@@ -163,6 +164,7 @@ function listen(port) {
163164
cache: argv.c,
164165
timeout: argv.t,
165166
showDir: argv.d,
167+
dirOverrides404: argv['dir-overrides-404'],
166168
baseDir: baseDir,
167169
autoIndex: argv.i,
168170
gzip: argv.g || argv.gzip,

doc/http-server.1

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ Default is 0.0.0.0.
3333
Show directory listings.
3434
Default is true.
3535

36+
.TP
37+
.BI \-d
38+
Whether -d should override magic 404.html
39+
Default is false.
40+
3641
.TP
3742
.BI \-i
3843
Display autoIndex.

lib/core/aliases.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
{
22
"autoIndex": [ "autoIndex", "autoindex" ],
33
"showDir": [ "showDir", "showdir" ],
4+
"dirOverrides404": [
5+
"dirOverrides404",
6+
"diroverrides404",
7+
"dir-overrides-404",
8+
"listingsOverride404",
9+
"listings-override-404"
10+
],
411
"showDotfiles": ["showDotfiles", "showdotfiles"],
512
"humanReadable": [ "humanReadable", "humanreadable", "human-readable" ],
613
"hidePermissions": ["hidePermissions", "hidepermissions", "hide-permissions"],

lib/core/defaults.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"autoIndex": true,
33
"showDir": true,
4+
"dirOverrides404": false,
45
"showDotfiles": true,
56
"humanReadable": true,
67
"hidePermissions": false,

lib/core/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,11 @@ module.exports = function createMiddleware(_dir, _options) {
364364
url: `${parsed.pathname}.${defaultExt}${(parsed.search) ? parsed.search : ''}`,
365365
headers: req.headers,
366366
}, res, next);
367+
} else if (opts.showDir && opts.dirOverrides404) {
368+
// If showDir and dirOverrides404 are true, show the directory instead of 404.html
369+
req.url = path.dirname(req.url);
370+
showDir(opts, stat)(req, res);
371+
return;
367372
} else {
368373
// Try to serve default ./404.html
369374
const rawUrl = (handleError ? `/${path.join(baseDir, `404.${defaultExt}`)}` : req.url);
@@ -411,7 +416,6 @@ module.exports = function createMiddleware(_dir, _options) {
411416
showDir(opts, stat)(req, res);
412417
return;
413418
}
414-
415419
status[403](res, next);
416420
});
417421
return;

lib/core/opts.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const aliases = require('./aliases.json');
88
module.exports = (opts) => {
99
let autoIndex = defaults.autoIndex;
1010
let showDir = defaults.showDir;
11+
let dirOverrides404 = defaults.dirOverrides404;
1112
let showDotfiles = defaults.showDotfiles;
1213
let humanReadable = defaults.humanReadable;
1314
let hidePermissions = defaults.hidePermissions;
@@ -70,6 +71,14 @@ module.exports = (opts) => {
7071
return false;
7172
});
7273

74+
aliases.dirOverrides404.some((k) => {
75+
if (isDeclared(k)) {
76+
dirOverrides404 = opts[k];
77+
return true;
78+
}
79+
return false;
80+
});
81+
7382
aliases.showDotfiles.some((k) => {
7483
if (isDeclared(k)) {
7584
showDotfiles = opts[k];
@@ -202,6 +211,7 @@ module.exports = (opts) => {
202211
cache,
203212
autoIndex,
204213
showDir,
214+
dirOverrides404,
205215
showDotfiles,
206216
humanReadable,
207217
hidePermissions,

lib/http-server.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ function HttpServer(options) {
6969
options.cache // in seconds.
7070
);
7171
this.showDir = options.showDir !== 'false';
72+
this.dirOverrides404 = options.dirOverrides404;
7273
this.autoIndex = options.autoIndex !== 'false';
7374
this.showDotfiles = options.showDotfiles;
7475
this.gzip = options.gzip === true;
@@ -153,6 +154,7 @@ function HttpServer(options) {
153154
showDotfiles: this.showDotfiles,
154155
autoIndex: this.autoIndex,
155156
defaultExt: this.ext,
157+
dirOverrides404: this.dirOverrides404,
156158
gzip: this.gzip,
157159
brotli: this.brotli,
158160
forceContentEncoding: this.forceContentEncoding,

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@
8282
{
8383
"name": "Jade Michael Thornton",
8484
"email": "[email protected]"
85+
},
86+
{
87+
"name": "Jorens Merenjanu",
88+
"email": "[email protected]"
8589
}
8690
],
8791
"dependencies": {

test/dir-overrides-404.test.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
'use strict';
2+
3+
const test = require('tap').test;
4+
const http = require('http');
5+
const ecstatic = require('../lib/core');
6+
const request = require('request');
7+
const showDir = require('../lib/core/show-dir');
8+
9+
const root = `${__dirname}/public/dir-overrides-404`;
10+
11+
test('server should display directory if -d and --dir-overrides--404 flags are specified', (t) => {
12+
// require('portfinder').getPort((err, port) => {
13+
try {
14+
const server = http.createServer(ecstatic({root, showDir: true, dirOverrides404: true}));
15+
// t.plan(2);
16+
// t.on('end', () => { server.close(); });
17+
server.listen(0, () => {
18+
const port = server.address().port;
19+
request.get(`http://localhost:${port}/directory/`, (err, res, body) => {
20+
if(err) {
21+
t.error(err);
22+
}
23+
// console.log(body);
24+
// console.log(res.statusCode);
25+
t.equal(res.statusCode, 200);
26+
console.log(body);
27+
t.equal(body.includes('Index of /directory/'), true);
28+
server.close(() => { t.end(); });
29+
});
30+
})
31+
console.log('d');
32+
33+
} catch (e) {
34+
t.fail(e.message);
35+
t.end();
36+
}
37+
// });
38+
});
39+
40+
test('server should display 404.html if -d flag is specified but not --dir-overrides-404', (t) => {
41+
try {
42+
const server = http.createServer(ecstatic({root, showDir: true, dirOverrides404: false}));
43+
// t.plan(2);
44+
// t.on('end', () => { server.close(); });
45+
server.listen(0, () => {
46+
const port = server.address().port;
47+
request.get(`http://localhost:${port}/directory/`, (err, res, body) => {
48+
if(err) {
49+
t.error(err);
50+
}
51+
t.equal(res.statusCode, 404);
52+
t.equal(body.includes('404file'), true);
53+
server.close(() => { t.end(); });
54+
});
55+
})
56+
console.log('d');
57+
58+
} catch (e) {
59+
t.fail(e.message);
60+
t.end();
61+
}
62+
63+
});

0 commit comments

Comments
 (0)