Last active
August 29, 2015 14:07
-
-
Save majimboo/094463a89dce660a96e6 to your computer and use it in GitHub Desktop.
Express serve-static that can be toggled on/off
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* serve-static | |
* Copyright(c) 2010 Sencha Inc. | |
* Copyright(c) 2011 TJ Holowaychuk | |
* Copyright(c) 2014 Douglas Christopher Wilson | |
* MIT Licensed | |
* | |
* Used as an answer to: | |
* http://stackoverflow.com/questions/26388122 | |
*/ | |
/** | |
* Module dependencies. | |
*/ | |
var escapeHtml = require('escape-html'); | |
var merge = require('utils-merge'); | |
var parseurl = require('parseurl'); | |
var resolve = require('path').resolve; | |
var send = require('send'); | |
var url = require('url'); | |
/** | |
* @param {String} root | |
* @param {Object} options | |
* @return {Function} | |
* @api public | |
*/ | |
exports = module.exports = function serveStatic(root, options) { | |
if (!root) { | |
throw new TypeError('root path required') | |
} | |
if (typeof root !== 'string') { | |
throw new TypeError('root path must be a string') | |
} | |
// copy options object | |
options = merge({}, options) | |
// resolve root to absolute | |
root = resolve(root) | |
// default redirect | |
var redirect = options.redirect !== false | |
// headers listener | |
var setHeaders = options.setHeaders | |
delete options.setHeaders | |
if (setHeaders && typeof setHeaders !== 'function') { | |
throw new TypeError('option setHeaders must be function') | |
} | |
// setup options for send | |
options.maxage = options.maxage || options.maxAge || 0 | |
options.root = root | |
return function serveStatic(req, res, next) { | |
if (req.method !== 'GET' && req.method !== 'HEAD') { | |
return next() | |
} | |
// disable based on session variable | |
// load session middleware before this | |
if (req.session && req.session.loggedIn === false) { | |
return next() | |
} | |
var opts = merge({}, options) | |
var originalUrl = parseurl.original(req) | |
var path = parseurl(req).pathname | |
var hasTrailingSlash = originalUrl.pathname[originalUrl.pathname.length - 1] === '/' | |
if (path === '/' && !hasTrailingSlash) { | |
// make sure redirect occurs at mount | |
path = '' | |
} | |
// create send stream | |
var stream = send(req, path, opts) | |
if (redirect) { | |
// redirect relative to originalUrl | |
stream.on('directory', function redirect() { | |
if (hasTrailingSlash) { | |
return next() | |
} | |
originalUrl.pathname += '/' | |
var target = url.format(originalUrl) | |
res.statusCode = 303 | |
res.setHeader('Content-Type', 'text/html; charset=utf-8') | |
res.setHeader('Location', target) | |
res.end('Redirecting to <a href="' + escapeHtml(target) + '">' + escapeHtml(target) + '</a>\n') | |
}) | |
} else { | |
// forward to next middleware on directory | |
stream.on('directory', next) | |
} | |
// add headers listener | |
if (setHeaders) { | |
stream.on('headers', setHeaders) | |
} | |
// forward non-404 errors | |
stream.on('error', function error(err) { | |
next(err.status === 404 ? null : err) | |
}) | |
// pipe | |
stream.pipe(res) | |
} | |
} | |
/** | |
* Expose mime module. | |
* | |
* If you wish to extend the mime table use this | |
* reference to the "mime" module in the npm registry. | |
*/ | |
exports.mime = send.mime |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment