mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-28 05:14:12 +03:00
35bc5fa08a
We're planning to change this from a warning to an error and need to clean the codebase up before we do so. In all of these cases the shadowing was known about and was not causing unexpected behaviour, so the refactor consists entirely of renaming, rather than refactoring/bug fixes.
294 lines
8.6 KiB
JavaScript
294 lines
8.6 KiB
JavaScript
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();
|
|
});
|
|
}
|