/*! * vhost * Copyright(c) 2014 Jonathan Ong * Copyright(c) 2014 Douglas Christopher Wilson * MIT Licensed */ /** * Create a vhost middleware. * * @param {string|RegExp} hostname * @param {function} handle * @return {Function} * @api public */ module.exports = 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} * @api 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} * @api private */ function isregexp(val){ return Object.prototype.toString.call(val) === '[object RegExp]' } /** * Generate RegExp for given hostname value. * * @param (string|RegExp} val * @api private */ function hostregexp(val){ var source = !isregexp(val) ? String(val).replace(/([.+?^=!:${}()|\[\]\/\\])/g, '\\$1').replace(/\*/g, '([^\.]+)') : val.source // force leading anchor matching if (source[0] !== '^') { source = '^' + source } // force trailing anchor matching source = source.replace(/(\\*)(.)$/, function(s, b, c){ return c !== '$' || b.length % 2 === 1 ? s + '$' : s }) return new RegExp(source, 'i') } /** * Get the vhost data of the request for RegExp * * @param (object} req * @param (RegExp} regexp * @return {object} * @api 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 }