diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 9a351f0..36349e5 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -67,3 +67,4 @@ Listed in no particular order: * Victor Didenko @victordidenko * Zong Jhe Wu @s25g5d4 * Jade Michael Thornton @thornjad +* Jack Lu @panlina diff --git a/README.md b/README.md index e82247f..e1cd222 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,6 @@ In node, pass ecstatic an options hash, and it will return your middleware! ```js const opts = { root: path.join(__dirname, 'public'), - baseDir: '/', autoIndex: true, showDir: true, showDotfiles: true, @@ -128,14 +127,6 @@ In CLI mode, `opts.port` is the port you want ecstatic to listen to. Defaults to 8000. This can be overridden with the `--port` flag or with the PORT environment variable. -### `opts.baseDir` -### `--baseDir {dir}` - -`opts.baseDir` is `/` by default, but can be changed to allow your static files -to be served off a specific route. For example, if `opts.baseDir === "blog"` -and `opts.root = "./public"`, requests for `localhost:8080/blog/index.html` will -resolve to `./public/index.html`. - ### `opts.cache` ### `--cache {value}` diff --git a/lib/ecstatic.js b/lib/ecstatic.js index 7827408..fa6fb19 100644 --- a/lib/ecstatic.js +++ b/lib/ecstatic.js @@ -97,7 +97,6 @@ module.exports = function createMiddleware(_dir, _options) { const opts = optsParser(options); const cache = opts.cache; const autoIndex = opts.autoIndex; - const baseDir = opts.baseDir; let defaultExt = opts.defaultExt; const handleError = opts.handleError; const headers = opts.headers; @@ -206,7 +205,7 @@ module.exports = function createMiddleware(_dir, _options) { file = path.normalize( path.join( root, - path.relative(path.join('/', baseDir), pathname) + pathname ) ); // determine compressed forms if they were to exist @@ -357,13 +356,15 @@ module.exports = function createMiddleware(_dir, _options) { // If there is no file extension in the path and we have a default // extension try filename and default extension combination before rendering 404.html. middleware({ + baseUrl: req.baseUrl, url: `${parsed.pathname}.${defaultExt}${(parsed.search) ? parsed.search : ''}`, headers: req.headers, }, res, next); } else { // Try to serve default ./404.html middleware({ - url: (handleError ? `/${path.join(baseDir, `404.${defaultExt}`)}` : req.url), + baseUrl: req.baseUrl, + url: (handleError ? `/404.${defaultExt}` : req.url), headers: req.headers, statusCode: 404, }, res, next); @@ -380,13 +381,14 @@ module.exports = function createMiddleware(_dir, _options) { if (!parsed.pathname.match(/\/$/)) { res.statusCode = 302; const q = parsed.query ? `?${parsed.query}` : ''; - res.setHeader('location', `${parsed.pathname}/${q}`); + res.setHeader('location', `${req.baseUrl || ''}${parsed.pathname}/${q}`); res.end(); return; } if (autoIndex) { middleware({ + baseUrl: req.baseUrl, url: urlJoin( encodeURIComponent(pathname), `/index.${defaultExt}` diff --git a/lib/ecstatic/opts.js b/lib/ecstatic/opts.js index d4b170d..ae64b98 100644 --- a/lib/ecstatic/opts.js +++ b/lib/ecstatic/opts.js @@ -198,7 +198,6 @@ module.exports = (opts) => { hidePermissions, si, defaultExt, - baseDir: (opts && opts.baseDir) || '/', gzip, brotli, handleError, diff --git a/lib/ecstatic/show-dir/index.js b/lib/ecstatic/show-dir/index.js index 573c172..852583b 100644 --- a/lib/ecstatic/show-dir/index.js +++ b/lib/ecstatic/show-dir/index.js @@ -18,7 +18,6 @@ module.exports = (opts) => { // opts are parsed by opts.js, defaults already applied const cache = opts.cache; const root = path.resolve(opts.root); - const baseDir = opts.baseDir; const humanReadable = opts.humanReadable; const hidePermissions = opts.hidePermissions; const handleError = opts.handleError; @@ -33,10 +32,7 @@ module.exports = (opts) => { const dir = path.normalize( path.join( root, - path.relative( - path.join('/', baseDir), - pathname - ) + pathname ) ); @@ -95,7 +91,7 @@ module.exports = (opts) => { const writeRow = (file) => { // render a row given a [name, stat] tuple const isDir = file[1].isDirectory && file[1].isDirectory(); - let href = `${parsed.pathname.replace(/\/$/, '')}/${encodeURIComponent(file[0])}`; + let href = `${req.baseUrl || ''}${parsed.pathname.replace(/\/$/, '')}/${encodeURIComponent(file[0])}`; // append trailing slash and query for dir entry if (isDir) { diff --git a/test/304.js b/test/304.js index 28a83af..28ce88f 100644 --- a/test/304.js +++ b/test/304.js @@ -2,27 +2,27 @@ const test = require('tap').test; const ecstatic = require('../lib/ecstatic'); +const express = require('express'); const http = require('http'); const request = require('request'); const path = require('path'); const root = `${__dirname}/public`; -const baseDir = 'base'; +const baseDir = '/base'; test('304_not_modified_strong', (t) => { const port = Math.floor((Math.random() * ((1 << 16) - 1e4)) + 1e4); const file = 'a.txt'; const server = http.createServer( - ecstatic({ + express().use(baseDir, ecstatic({ root, gzip: true, - baseDir, autoIndex: true, showDir: true, weakEtags: false, weakCompare: false, - }) + })) ); server.listen(port, () => { @@ -61,14 +61,13 @@ test('304_not_modified_weak', (t) => { const file = 'b.txt'; const server = http.createServer( - ecstatic({ + express().use(baseDir, ecstatic({ root, gzip: true, - baseDir, autoIndex: true, showDir: true, weakCompare: false, - }) + })) ); server.listen(port, () => { @@ -106,15 +105,14 @@ test('304_not_modified_strong_compare', (t) => { const file = 'b.txt'; const server = http.createServer( - ecstatic({ + express().use(baseDir, ecstatic({ root, gzip: true, - baseDir, autoIndex: true, showDir: true, weakEtags: false, weakCompare: false, - }) + })) ); server.listen(port, () => { @@ -174,14 +172,13 @@ test('304_not_modified_weak_compare', (t) => { const file = 'c.js'; const server = http.createServer( - ecstatic({ + express().use(baseDir, ecstatic({ root, gzip: true, - baseDir, autoIndex: true, showDir: true, weakEtags: false, - }) + })) ); server.listen(port, () => { diff --git a/test/core-error.js b/test/core-error.js index a063c76..026fe9e 100644 --- a/test/core-error.js +++ b/test/core-error.js @@ -2,13 +2,14 @@ const test = require('tap').test; const ecstatic = require('../lib/ecstatic'); +const express = require('express'); const http = require('http'); const request = require('request'); const mkdirp = require('mkdirp'); const path = require('path'); const root = `${__dirname}/public`; -const baseDir = 'base'; +const baseDir = '/base'; mkdirp.sync(`${root}/emptyDir`); @@ -19,14 +20,13 @@ test('core', (t) => { const port = Math.floor((Math.random() * ((1 << 16) - 1e4)) + 1e4); const server = http.createServer( - ecstatic({ + express().use(baseDir, ecstatic({ root, gzip: true, - baseDir, autoIndex: true, showDir: true, handleError: false, - }) + })) ); server.listen(port, () => { diff --git a/test/core.js b/test/core.js index 5e5400a..f85d336 100644 --- a/test/core.js +++ b/test/core.js @@ -2,6 +2,7 @@ const test = require('tap').test; const ecstatic = require('../lib/ecstatic'); +const express = require('express'); const http = require('http'); const request = require('request'); const mkdirp = require('mkdirp'); @@ -9,7 +10,7 @@ const path = require('path'); const eol = require('eol'); const root = `${__dirname}/public`; -const baseDir = 'base'; +const baseDir = '/base'; mkdirp.sync(`${root}/emptyDir`); @@ -20,15 +21,14 @@ test('core', (t) => { const port = Math.floor((Math.random() * ((1 << 16) - 1e4)) + 1e4); const server = http.createServer( - ecstatic({ + express().use(baseDir, ecstatic({ root, gzip: true, - baseDir, autoIndex: true, showDir: true, defaultExt: 'html', handleError: true, - }) + })) ); server.listen(port, () => { diff --git a/test/express-error.js b/test/express-error.js index 2daa216..90261ed 100644 --- a/test/express-error.js +++ b/test/express-error.js @@ -9,7 +9,7 @@ const mkdirp = require('mkdirp'); const path = require('path'); const root = `${__dirname}/public`; -const baseDir = 'base'; +const baseDir = '/base'; mkdirp.sync(`${root}/emptyDir`); @@ -21,10 +21,9 @@ test('express', (t) => { const app = express(); - app.use(ecstatic({ + app.use(baseDir, ecstatic({ root, gzip: true, - baseDir, autoIndex: true, showDir: true, cache: 'no-cache', diff --git a/test/express.js b/test/express.js index 89775d9..51bffed 100644 --- a/test/express.js +++ b/test/express.js @@ -10,7 +10,7 @@ const path = require('path'); const eol = require('eol'); const root = `${__dirname}/public`; -const baseDir = 'base'; +const baseDir = '/base'; mkdirp.sync(`${root}/emptyDir`); @@ -22,10 +22,9 @@ test('express', (t) => { const app = express(); - app.use(ecstatic({ + app.use(baseDir, ecstatic({ root, gzip: true, - baseDir, autoIndex: true, showDir: true, defaultExt: 'html', diff --git a/test/showdir-href-encoding.js b/test/showdir-href-encoding.js index d327859..15df3ea 100644 --- a/test/showdir-href-encoding.js +++ b/test/showdir-href-encoding.js @@ -2,24 +2,24 @@ const test = require('tap').test; const ecstatic = require('../lib/ecstatic'); +const express = require('express'); const http = require('http'); const request = require('request'); const path = require('path'); const root = `${__dirname}/public`; -const baseDir = 'base'; +const baseDir = '/base'; test('url encoding in href', (t) => { const port = Math.floor((Math.random() * ((1 << 16) - 1e4)) + 1e4); const uri = `http://localhost:${port}${path.join('/', baseDir, 'show-dir%24%24href_encoding%24%24')}`; const server = http.createServer( - ecstatic({ + express().use(baseDir, ecstatic({ root, - baseDir, showDir: true, autoIndex: false, - }) + })) ); server.listen(port, () => { diff --git a/test/showdir-pathname-encoding.js b/test/showdir-pathname-encoding.js index 227a9c4..d59b39c 100644 --- a/test/showdir-pathname-encoding.js +++ b/test/showdir-pathname-encoding.js @@ -2,6 +2,7 @@ const tap = require('tap'); const ecstatic = require('../lib/ecstatic'); +const express = require('express'); const http = require('http'); const request = require('request'); const path = require('path'); @@ -9,7 +10,7 @@ const path = require('path'); const test = tap.test; const root = `${__dirname}/public`; -const baseDir = 'base'; +const baseDir = '/base'; if (process.platform === 'win32') { tap.plan(0, 'Windows is allergic to < in path names'); @@ -29,12 +30,11 @@ test('directory listing with pathname including HTML characters', (t) => { const uri = `http://localhost:${port}${path.join('/', baseDir, '/%3Cdir%3E')}`; const server = http.createServer( - ecstatic({ + express().use(baseDir, ecstatic({ root, - baseDir, showDir: true, autoIndex: false, - }) + })) ); server.listen(port, () => { diff --git a/test/showdir-search-encoding.js b/test/showdir-search-encoding.js index ed6a0c6..2b81ce9 100644 --- a/test/showdir-search-encoding.js +++ b/test/showdir-search-encoding.js @@ -2,24 +2,24 @@ const test = require('tap').test; const ecstatic = require('../lib/ecstatic'); +const express = require('express'); const http = require('http'); const request = require('request'); const path = require('path'); const root = `${__dirname}/public`; -const baseDir = 'base'; +const baseDir = '/base'; test('directory listing with query string specified', (t) => { const port = Math.floor((Math.random() * ((1 << 16) - 1e4)) + 1e4); const uri = `http://localhost:${port}${path.join('/', baseDir, '?a=1&b=2')}`; const server = http.createServer( - ecstatic({ + express().use(baseDir, ecstatic({ root, - baseDir, showDir: true, autoIndex: false, - }) + })) ); server.listen(port, () => { diff --git a/test/showdir-with-spaces.js b/test/showdir-with-spaces.js index fdee160..3e1c3ac 100644 --- a/test/showdir-with-spaces.js +++ b/test/showdir-with-spaces.js @@ -2,24 +2,24 @@ const test = require('tap').test; const ecstatic = require('../lib/ecstatic'); +const express = require('express'); const http = require('http'); const request = require('request'); const path = require('path'); const root = `${__dirname}/public`; -const baseDir = 'base'; +const baseDir = '/base'; test('directory listing when directory name contains spaces', (t) => { const port = Math.floor((Math.random() * ((1 << 16) - 1e4)) + 1e4); const uri = `http://localhost:${port}${path.join('/', baseDir, 'subdir_with%20space')}`; const server = http.createServer( - ecstatic({ + express().use(baseDir, ecstatic({ root, - baseDir, showDir: true, autoIndex: false, - }) + })) ); server.listen(port, () => {