/*! * vhost * Copyright(c) 2014 Jonathan Ong * Copyright(c) 2014-2015 Douglas Christopher Wilson * MIT Licensed */ 'use strict' /** * Module exports. * @public */ module.exports = vhost /** * Module variables. * @private */ var asteriskRegExp = /\*/g var asteriskReplace = '([^\.]+)' var endAnchoredRegExp = /(?:^|[^\\])(?:\\\\)*\$$/ var escapeRegExp = /([.+?^=!:${}()|\[\]\/\\])/g var escapeReplace = '\\$1' /** * Create a vhost middleware. * * @param {string|RegExp} hostname * @param {function} handle * @return {Function} * @public */ function vhost(hostname, handle) { if (!hostname) { throw new TypeError('argument hostname is required') } if (!handle) { throw new TypeError('argument handle is required') } if (typeof handle !== 'function') { throw new TypeError('argument handle must be a function') } // create regular expression for hostname var regexp = hostregexp(hostname) return function vhost(req, res, next) { var vhostdata = vhostof(req, regexp) if (!vhostdata) { return next() } // populate req.vhost = vhostdata // handle handle(req, res, next) } } /** * Get hostname of request. * * @param (object} req * @return {string} * @private */ function hostnameof(req) { var host = req.headers.host if (!host) { return } var offset = host[0] === '[' ? host.indexOf(']') + 1 : 0 var index = host.indexOf(':', offset) return index !== -1 ? host.substring(0, index) : host } /** * Determine if object is RegExp. * * @param (object} val * @return {boolean} * @private */ function isregexp(val) { return Object.prototype.toString.call(val) === '[object RegExp]' } /** * Generate RegExp for given hostname value. * * @param (string|RegExp} val * @private */ function hostregexp(val) { var source = !isregexp(val) ? String(val).replace(escapeRegExp, escapeReplace).replace(asteriskRegExp, asteriskReplace) : val.source // force leading anchor matching if (source[0] !== '^') { source = '^' + source } // force trailing anchor matching if (!endAnchoredRegExp.test(source)) { source += '$' } return new RegExp(source, 'i') } /** * Get the vhost data of the request for RegExp * * @param (object} req * @param (RegExp} regexp * @return {object} * @private */ function vhostof(req, regexp) { var host = req.headers.host var hostname = hostnameof(req) if (!hostname) { return } var match = regexp.exec(hostname) if (!match) { return } var obj = Object.create(null) obj.host = host obj.hostname = hostname obj.length = match.length - 1 for (var i = 1; i < match.length; i++) { obj[i - 1] = match[i] } return obj }