From 1a401407b180e05aa4cee90b359d64001fe9cb68 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 | 23 +++++++++++--------
src/daemon/normalize.js | 12 ++++++++++
src/front/App.vue | 4 ++--
test/daemon/group.js | 49 +++++++++++++++++++++++++++++++++++++++++
5 files changed, 78 insertions(+), 11 deletions(-)
create mode 100644 src/daemon/normalize.js
diff --git a/package.json b/package.json
index e46475ad..1e276aef 100644
--- a/package.json
+++ b/package.json
@@ -60,6 +60,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 c4501d8a..8f959fe9 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')
@@ -61,15 +62,19 @@ class Group extends EventEmitter {
return this._list[id]
}
- 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`
@@ -97,7 +102,8 @@ class Group extends EventEmitter {
const mon = respawn(command, {
...conf,
- maxRestarts: 0
+ maxRestarts: 0,
+ name
})
this._list[id] = mon
@@ -145,7 +151,8 @@ class Group extends EventEmitter {
this._change()
}
- remove(id, cb) {
+ remove(name, cb) {
+ const id = normalize(name)
const item = this.find(id)
if (item) {
delete this._list[id]
@@ -204,10 +211,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..035276ff
--- /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(name) {
+ return name
+ ? punycode
+ .encode(name)
+ .toLowerCase()
+ .replace(/[^a-z0-9-.]/g, '-')
+ .replace(/-+/g, '-')
+ .replace(/-$/, '')
+ : name
+}
diff --git a/src/front/App.vue b/src/front/App.vue
index bf1e3d45..da33416d 100644
--- a/src/front/App.vue
+++ b/src/front/App.vue
@@ -26,7 +26,7 @@
{{ id }}
+ target="_blank">{{ item.name }}
+
\ No newline at end of file
diff --git a/test/daemon/group.js b/test/daemon/group.js
index b0517679..f9f30f7e 100644
--- a/test/daemon/group.js
+++ b/test/daemon/group.js
@@ -19,6 +19,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'