/usr/lib/nodejs/serve-static/index.js is in node-serve-static 1.6.4-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | /*!
* serve-static
* Copyright(c) 2010 Sencha Inc.
* Copyright(c) 2011 TJ Holowaychuk
* Copyright(c) 2014 Douglas Christopher Wilson
* MIT Licensed
*/
/**
* 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()
}
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()
}
// append trailing slash
originalUrl.pathname = collapseLeadingSlashes(originalUrl.pathname + '/')
// reformat the URL
var target = url.format(originalUrl)
// send redirect response
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
/**
* Collapse all leading slashes into a single slash
* @private
*/
function collapseLeadingSlashes(str) {
for (var i = 0; i < str.length; i++) {
if (str[i] !== '/') {
break
}
}
return i > 1
? '/' + str.substr(i)
: str
}
|