diff --git a/README.md b/README.md index a22c410..fbc24d4 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,13 @@ To allow fall through to your custom routes: ecstatic({ root: __dirname + '/public', handleError: false }) ``` +### fallback file +To response with specified file: + +```js +ecstatic({ root: __dirname + '/public', fallbackFile: 'index.html' }) +``` + # API: ## ecstatic(opts); @@ -76,6 +83,7 @@ var opts = { serverHeader : true, contentType : 'application/octet-stream', mimeTypes : undefined, + fallbackFile : undefined handleOptionsMethod: false } ``` @@ -83,7 +91,7 @@ var opts = { If `opts` is a string, the string is assigned to the root folder and all other options are set to their defaults. -### `opts.root` +### `opts.root` `opts.root` is the directory you want to serve up. @@ -160,7 +168,7 @@ Defaults to **application/octet-stream**. Add new or override one or more mime-types. This affects the HTTP Content-Type header. Can either be a path to a [`.types`](http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types) file or an object hash of type(s). - + ecstatic({ mimeType: { 'mime-type': ['file_extension', 'file_extension'] } }) ### `opts.handleError` diff --git a/lib/ecstatic.js b/lib/ecstatic.js index ac57fda..4d03b1e 100755 --- a/lib/ecstatic.js +++ b/lib/ecstatic.js @@ -28,6 +28,7 @@ var ecstatic = module.exports = function (dir, options) { handleError = opts.handleError, headers = opts.headers, serverHeader = opts.serverHeader, + fallbackFile = opts.fallbackFile; weakEtags = opts.weakEtags, handleOptionsMethod = opts.handleOptionsMethod; @@ -108,6 +109,11 @@ var ecstatic = module.exports = function (dir, options) { url: parsed.pathname + '.' + defaultExt + ((parsed.search)? parsed.search:'') }, res, next); } + else if (fallbackFile) { + middleware({ + url: ('/' + path.join(baseDir, fallbackFile)) + }, res, next); + } else { // Try to serve default ./404.html middleware({ @@ -273,7 +279,7 @@ var ecstatic = module.exports = function (dir, options) { } if (clientEtag) { - if (opts.weakCompare && clientEtag !== serverEtag + if (opts.weakCompare && clientEtag !== serverEtag && clientEtag !== ('W/' + serverEtag) && ('W/' + clientEtag) !== serverEtag) { return false; } else if (!opts.weakCompare && (clientEtag !== serverEtag || clientEtag.indexOf('W/') === 0)) { diff --git a/lib/ecstatic/aliases.json b/lib/ecstatic/aliases.json index 4b0ac66..8e6edc3 100644 --- a/lib/ecstatic/aliases.json +++ b/lib/ecstatic/aliases.json @@ -29,5 +29,10 @@ "handleOptionsMethod", "handleoptionsmethod", "handle-options-method" + ], + "fallbackFile": [ + "fallbackFile", + "fallbackfile", + "fallback-file" ] } diff --git a/lib/ecstatic/opts.js b/lib/ecstatic/opts.js index 42bac95..4aac4aa 100644 --- a/lib/ecstatic/opts.js +++ b/lib/ecstatic/opts.js @@ -15,6 +15,7 @@ module.exports = function (opts) { headers = {}, serverHeader = defaults.serverHeader, contentType = defaults.contentType, + fallbackFile, mimeTypes, weakEtags = defaults.weakEtags, weakCompare = defaults.weakCompare, @@ -104,6 +105,13 @@ module.exports = function (opts) { } }); + aliases.fallbackFile.some(function (k) { + if (isDeclared(k)) { + fallbackFile = opts[k]; + return true; + } + }); + aliases.serverHeader.some(function (k) { if (isDeclared(k)) { serverHeader = opts[k]; @@ -158,6 +166,7 @@ module.exports = function (opts) { gzip: gzip, handleError: handleError, headers: headers, + fallbackFile: fallbackFile, serverHeader: serverHeader, contentType: contentType, mimeTypes: mimeTypes, diff --git a/test/custom-fallback-file.js b/test/custom-fallback-file.js new file mode 100644 index 0000000..e60edeb --- /dev/null +++ b/test/custom-fallback-file.js @@ -0,0 +1,29 @@ +var test = require('tap').test, + http = require('http'), + request = require('request'), + ecstatic = require('../'); + +test('custom fallbackFile', function(t) { + try { + var server = http.createServer(ecstatic({ + root: __dirname + '/public/', + fallbackFile: 'a.txt' + })); + } catch (e) { + t.fail(e.message); + t.end(); + } + + t.plan(4); + + server.listen(0, function() { + var port = server.address().port; + request.get('http://localhost:' + port + '/file-not-found', function(err, res, body) { + t.ifError(err); + t.equal(res.statusCode, 200, 'status code should be ok'); + t.equal(res.headers['content-type'], 'text/plain; charset=UTF-8'); + server.close(function() { t.end(); }); + t.equal('A!!!\n', body); + }); + }); +});