Ghost/ghost/mw-vhost/test/vhost.test.js

294 lines
8.6 KiB
JavaScript
Raw Normal View History

const assert = require('assert');
const http = require('http');
const request = require('supertest');
const vhost = require('..');
describe('vhost(hostname, server)', function () {
it('should route by Host', function (done) {
const vhosts = [];
vhosts.push(vhost('tobi.com', tobi));
vhosts.push(vhost('loki.com', loki));
const app = createServer(vhosts);
function tobi(req, res) {
res.end('tobi');
}
function loki(req, res) {
res.end('loki');
}
request(app)
.get('/')
.set('Host', 'tobi.com')
.expect(200, 'tobi', done);
});
it('should route by `req.hostname` (express v4)', function (done) {
const vhosts = [];
vhosts.push(vhost('anotherhost.com', anotherhost));
vhosts.push(vhost('loki.com', loki));
const app = createServer(vhosts, null, function (req) {
// simulate express setting req.hostname based on x-forwarded-host
req.hostname = 'anotherhost.com';
});
function anotherhost(req, res) {
res.end('anotherhost');
}
function loki(req, res) {
res.end('loki');
}
request(app)
.get('/')
.set('Host', 'loki.com')
.expect(200, 'anotherhost', done);
});
it('should ignore port in Host', function (done) {
const app = createServer('tobi.com', function (req, res) {
res.end('tobi');
});
request(app)
.get('/')
.set('Host', 'tobi.com:8080')
.expect(200, 'tobi', done);
});
it('should support IPv6 literal in Host', function (done) {
const app = createServer('[::1]', function (req, res) {
res.end('loopback');
});
request(app)
.get('/')
.set('Host', '[::1]:8080')
.expect(200, 'loopback', done);
});
it('should 404 unless matched', function (done) {
const vhosts = [];
vhosts.push(vhost('tobi.com', tobi));
vhosts.push(vhost('loki.com', loki));
const app = createServer(vhosts);
function tobi(req, res) {
res.end('tobi');
}
function loki(req, res) {
res.end('loki');
}
request(app)
.get('/')
.set('Host', 'ferrets.com')
.expect(404, done);
});
it('should 404 without Host header', function (done) {
const vhosts = [];
vhosts.push(vhost('tobi.com', tobi));
vhosts.push(vhost('loki.com', loki));
const server = createServer(vhosts);
const listeners = server.listeners('request');
server.removeAllListeners('request');
listeners.unshift(function (req) {
req.headers.host = undefined;
});
listeners.forEach(function (l) {
server.addListener('request', l);
});
function tobi(req, res) {
res.end('tobi');
}
function loki(req, res) {
res.end('loki');
}
request(server)
.get('/')
.expect(404, 'no vhost for "undefined"', done);
});
describe('arguments', function () {
describe('hostname', function () {
it('should be required', function () {
assert.throws(vhost.bind(), /hostname.*required/);
});
it('should accept string', function () {
assert.doesNotThrow(vhost.bind(null, 'loki.com', function () {}));
});
it('should accept RegExp', function () {
assert.doesNotThrow(vhost.bind(null, /loki\.com/, function () {}));
});
});
describe('handle', function () {
it('should be required', function () {
assert.throws(vhost.bind(null, 'loki.com'), /handle.*required/);
});
it('should accept function', function () {
assert.doesNotThrow(vhost.bind(null, 'loki.com', function () {}));
});
it('should reject plain object', function () {
assert.throws(vhost.bind(null, 'loki.com', {}), /handle.*function/);
});
});
});
describe('with string hostname', function () {
it('should support wildcards', function (done) {
const app = createServer('*.ferrets.com', function (req, res) {
res.end('wildcard!');
});
request(app)
.get('/')
.set('Host', 'loki.ferrets.com')
.expect(200, 'wildcard!', done);
});
it('should restrict wildcards to single part', function (done) {
const app = createServer('*.ferrets.com', function (req, res) {
res.end('wildcard!');
});
request(app)
.get('/')
.set('Host', 'foo.loki.ferrets.com')
.expect(404, done);
});
it('should treat dot as a dot', function (done) {
const app = createServer('a.b.com', function (req, res) {
res.end('tobi');
});
request(app)
.get('/')
.set('Host', 'aXb.com')
.expect(404, done);
});
it('should match entire string', function (done) {
const app = createServer('.com', function (req, res) {
res.end('commercial');
});
request(app)
.get('/')
.set('Host', 'foo.com')
.expect(404, done);
});
it('should populate req.vhost', function (done) {
const app = createServer('user-*.*.com', function (req, res) {
const keys = Object.keys(req.vhost).sort();
const arr = keys.map(function (k) {
return [k, req.vhost[k]];
});
res.end(JSON.stringify(arr));
});
request(app)
.get('/')
.set('Host', 'user-bob.foo.com:8080')
.expect(200, '[["0","bob"],["1","foo"],["host","user-bob.foo.com:8080"],["hostname","user-bob.foo.com"],["length",2]]', done);
});
});
describe('with RegExp hostname', function () {
it('should match using RegExp', function (done) {
const app = createServer(/[tl]o[bk]i\.com/, function (req, res) {
res.end('tobi');
});
request(app)
.get('/')
.set('Host', 'toki.com')
.expect(200, 'tobi', done);
});
it('should match entire hostname', function (done) {
const vhosts = [];
vhosts.push(vhost(/\.tobi$/, tobi));
vhosts.push(vhost(/^loki\./, loki));
const app = createServer(vhosts);
function tobi(req, res) {
res.end('tobi');
}
function loki(req, res) {
res.end('loki');
}
request(app)
.get('/')
.set('Host', 'loki.tobi.com')
.expect(404, done);
});
it('should populate req.vhost', function (done) {
const app = createServer(/user-(bob|joe)\.([^.]+)\.com/, function (req, res) {
const keys = Object.keys(req.vhost).sort();
const arr = keys.map(function (k) {
return [k, req.vhost[k]];
});
res.end(JSON.stringify(arr));
});
request(app)
.get('/')
.set('Host', 'user-bob.foo.com:8080')
.expect(200, '[["0","bob"],["1","foo"],["host","user-bob.foo.com:8080"],["hostname","user-bob.foo.com"],["length",2]]', done);
});
});
});
function createServer(hostname, server, pretest) {
const vhosts = !Array.isArray(hostname)
? [vhost(hostname, server)]
: hostname;
return http.createServer(function onRequest(req, res) {
// This allows you to perform changes to the request/response
// objects before our assertions
if (pretest) {
pretest(req, res);
}
let index = 0;
function next(err) {
const foundVhost = vhosts[index];
index = index + 1;
if (!foundVhost || err) {
res.statusCode = err ? (err.status || 500) : 404;
res.end(err ? err.message : `no vhost for "${req.headers.host}"`);
return;
}
foundVhost(req, res, next);
}
next();
});
}