From a6a7c227c015cc5a4c988a432526dc695ddc6ed4 Mon Sep 17 00:00:00 2001 From: Duncan Beevers Date: Sun, 6 Aug 2017 23:00:18 -0700 Subject: [PATCH] Separate hostname and displayed name of servers, use punycode hostname --- package.json | 1 + src/daemon/group.js | 30 ++++++++++++++----------- src/daemon/normalize.js | 12 ++++++++++ src/front/App.vue | 2 +- test/daemon/group.js | 49 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 14 deletions(-) create mode 100644 src/daemon/normalize.js diff --git a/package.json b/package.json index e8fedcd2..499ec680 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "once": "^1.3.2", "please-upgrade-node": "^3.0.0", "pug": "^2.0.0-beta11", + "punycode": "^2.1.0", "respawn": "^2.4.1", "server-ready": "^0.3.1", "strip-ansi": "^4.0.0", diff --git a/src/daemon/group.js b/src/daemon/group.js index 7e0df4c6..1a141348 100644 --- a/src/daemon/group.js +++ b/src/daemon/group.js @@ -10,6 +10,7 @@ const afterAll = require('after-all') const httpProxy = require('http-proxy') const serverReady = require('server-ready') const log = require('./log') +const normalize = require('./normalize') const tcpProxy = require('./tcp-proxy') const daemonConf = require('../conf') const getCmd = require('../get-cmd') @@ -53,19 +54,23 @@ class Group extends EventEmitter { return this._list } - find(id) { - return this._list[id] + find(name) { + return this._list[normalize(name)] } - add(id, conf) { + add(name, conf) { + conf.name = name + const id = normalize(name) + if (conf.target) { - log(`Add target ${id}`) + log(`Add target ${name}`) this._list[id] = conf + this._change() return } - log(`Add server ${id}`) + log(`Add server ${name}`) const HTTP_PROXY = `http://127.0.0.1:${daemonConf.port}/proxy.pac` @@ -93,7 +98,8 @@ class Group extends EventEmitter { const mon = respawn(command, { ...conf, - maxRestarts: 0 + maxRestarts: 0, + name }) this._list[id] = mon @@ -141,10 +147,10 @@ class Group extends EventEmitter { this._change() } - remove(id, cb) { - const item = this.find(id) + remove(name, cb) { + const item = this.find(name) if (item) { - delete this._list[id] + delete this._list[normalize(name)] this._change() if (item.stop) { @@ -197,10 +203,8 @@ class Group extends EventEmitter { exists(req, res, next) { // Resolve using either hostname `app.tld` // or id param `http://localhost:2000/app` - const tld = new RegExp(`.${daemonConf.tld}$`) - const id = req.params.id - ? this.resolve(req.params.id) - : this.resolve(req.hostname.replace(tld, '')) + const tld = new RegExp(`\\.${daemonConf.tld}$`) + const id = this.resolve(req.params.id || req.hostname.replace(tld, '')) // Find item const item = this.find(id) diff --git a/src/daemon/normalize.js b/src/daemon/normalize.js new file mode 100644 index 00000000..16fb4d95 --- /dev/null +++ b/src/daemon/normalize.js @@ -0,0 +1,12 @@ +const punycode = require('punycode') // eslint-disable-line node/no-deprecated-api + +module.exports = function normalize(id) { + return id + ? punycode + .encode(id) + .toLowerCase() + .replace(/[^a-z0-9-.]/g, '-') + .replace(/-+/g, '-') + .replace(/-$/, '') + : id +} diff --git a/src/front/App.vue b/src/front/App.vue index 0a6f308a..d40be7f2 100644 --- a/src/front/App.vue +++ b/src/front/App.vue @@ -22,7 +22,7 @@ {{ id }} + :target="target">{{ item.name }}
{{item.status}} diff --git a/test/daemon/group.js b/test/daemon/group.js index ac26523e..627a2258 100644 --- a/test/daemon/group.js +++ b/test/daemon/group.js @@ -18,6 +18,55 @@ test('group.resolve should find the correct server or target id', t => { t.is(group.resolve('baz.foo.app'), 'foo.app') }) +test('group.exists should 404 on missing id', t => { + const group = Group() + const conf = { target: 'http://example.com' } + + group.add('app', conf) + + const request = { params: { id: 'bar' }, hostname: 'localhost' } + + const sendSpy = sinon.stub() + const statusSpy = sinon.stub().returns({ send: sendSpy }) + const response = { status: statusSpy } + + group.exists(request, response) + + t.is(statusSpy.callCount, 1) + t.is(statusSpy.lastCall.args[0], 404) + t.is(sendSpy.callCount, 1) +}) + +test.cb('group.exists should find group by param', t => { + const group = Group() + const conf = { target: 'http://example.com' } + + group.add('App Foo', conf) + + const request = { params: { id: 'app-foo' }, hostname: 'localhost' } + const response = {} + + group.exists(request, response, () => { + t.is(request.hotel.id, 'app-foo') + t.end() + }) +}) + +test.cb('group.exists should find group by hostname', t => { + const group = Group() + const conf = { target: 'http://example.com' } + + group.add('bar-baz-∫', conf) + + const request = { params: {}, hostname: 'bar-baz-tl7d.dev' } + const response = {} + + group.exists(request, response, () => { + t.is(request.hotel.id, 'bar-baz-tl7d') + t.end() + }) +}) + test('group.handleUpgrade with proxy', t => { const group = Group() const target = 'example.com'