hotel
Advanced tools
Comparing version 0.5.13 to 0.6.0
# Change Log | ||
## 0.6.0 | ||
* Add `--xfwd` and `--change-origin` flags to `hotel add` command | ||
* Log proxy errors | ||
__Breaking__ | ||
* If you want hotel to add `X-Forwarded-*` headers to requests, you need now to explicitly pass `-x/--xfwd` flags when adding a server. | ||
## 0.5.13 | ||
* Fix `hotel add` CLI bug | ||
## 0.5.12 | ||
* Add dark theme | ||
* Update `x-forward-port` header | ||
* Update `X-Forwarded-Port` header | ||
* Improve `ember-cli` and `livereload` support | ||
@@ -11,3 +24,3 @@ | ||
* Add more `x-forward` headers | ||
* Add more `X-Forwarded-*` headers | ||
@@ -14,0 +27,0 @@ ## 0.5.10 |
@@ -13,2 +13,6 @@ 'use strict'; | ||
describe: 'Server name' | ||
}).option('port', { | ||
alias: 'p', | ||
describe: 'Set PORT environment variable', | ||
number: true | ||
}).option('out', { | ||
@@ -19,7 +23,14 @@ alias: 'o', | ||
alias: 'e', | ||
array: true, | ||
describe: 'Additional environment variables' | ||
}).option('port', { | ||
alias: 'p', | ||
describe: 'Set PORT environment variable' | ||
describe: 'Additional environment variables', | ||
array: true | ||
}).option('xfwd', { | ||
alias: 'x', | ||
describe: 'Adds x-forward headers', | ||
default: false, | ||
boolean: true | ||
}).option('change-origin', { | ||
alias: 'co', | ||
describe: 'Changes the origin of the host header to the target URL', | ||
default: false, | ||
boolean: true | ||
}).demand(1); | ||
@@ -26,0 +37,0 @@ }, function (argv) { |
'use strict'; | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var fs = require('fs'); | ||
@@ -45,16 +47,25 @@ var path = require('path'); | ||
var cwd = opts.d || process.cwd(); | ||
var id = opts.n || getId(cwd); | ||
var cwd = opts.dir || process.cwd(); | ||
var id = opts.name || getId(cwd); | ||
var file = getServerFile(id); | ||
var conf = void 0; | ||
var conf = {}; | ||
if (opts.xfwd) { | ||
conf.xfwd = opts.xfwd; | ||
} | ||
if (opts.changeOrigin) { | ||
conf.changeOrigin = opts.changeOrigin; | ||
} | ||
if (isUrl(param)) { | ||
conf = { | ||
conf = _extends({ | ||
target: param | ||
}; | ||
}, conf); | ||
} else { | ||
conf = { | ||
conf = _extends({ | ||
cwd: cwd, | ||
cmd: param | ||
}; | ||
}, conf); | ||
@@ -69,4 +80,4 @@ if (opts.o) conf.out = opts.o; | ||
// Copy other env option | ||
if (opts.e) { | ||
opts.e.forEach(function (key) { | ||
if (opts.env) { | ||
opts.env.forEach(function (key) { | ||
var value = process.env[key]; | ||
@@ -80,4 +91,4 @@ if (value) { | ||
// Copy port option | ||
if (opts.p) { | ||
conf.env.PORT = opts.p; | ||
if (opts.port) { | ||
conf.env.PORT = opts.port; | ||
} | ||
@@ -84,0 +95,0 @@ } |
@@ -47,3 +47,5 @@ 'use strict'; | ||
_this._list = {}; | ||
_this._proxy = httpProxy.createProxyServer({ xfwd: true }); | ||
_this._proxy = httpProxy.createProxyServer({ | ||
xfwd: true | ||
}); | ||
_this._proxy.on('error', _this.handleProxyError); | ||
@@ -129,2 +131,6 @@ return _this; | ||
// Add proxy config | ||
mon.xfwd = conf.xfwd || false; | ||
mon.changeOrigin = conf.changeOrigin || false; | ||
// Emit output | ||
@@ -273,5 +279,5 @@ mon.on('stdout', function (data) { | ||
key: 'handleProxyError', | ||
value: function handleProxyError(_, req, res) { | ||
util.log('Proxy error'); | ||
var msg = errorMsg(req.hotel.item); | ||
value: function handleProxyError(err, req, res) { | ||
util.log('Proxy error -', err.message); | ||
var msg = errorMsg(err, req.hotel.item); | ||
res.status(502).send(msg); | ||
@@ -356,4 +362,12 @@ } | ||
var target = 'http://127.0.0.1:' + port; | ||
var xfwd = item.xfwd, | ||
changeOrigin = item.changeOrigin; | ||
util.log('Proxy http://' + req.headers.host + ' to ' + target); | ||
return this._proxy.web(req, res, { target: target }); | ||
return this._proxy.web(req, res, { | ||
target: target, | ||
xfwd: xfwd, | ||
changeOrigin: changeOrigin | ||
}); | ||
} | ||
@@ -363,4 +377,13 @@ | ||
var send = once(function () { | ||
util.log('Proxy http://' + hostname + ' to ' + item.target); | ||
_this5._proxy.web(req, res, { target: item.target }); | ||
var target = item.target, | ||
xfwd = item.xfwd, | ||
changeOrigin = item.changeOrigin; | ||
util.log('Proxy http://' + hostname + ' to ' + target); | ||
_this5._proxy.web(req, res, { | ||
target: target, | ||
xfwd: xfwd, | ||
changeOrigin: changeOrigin | ||
}); | ||
}); | ||
@@ -367,0 +390,0 @@ |
@@ -7,3 +7,3 @@ 'use strict'; | ||
// Simple error message used in vhosts/dev and router | ||
module.exports = function (server) { | ||
module.exports = function (err, server) { | ||
if (server.start) { | ||
@@ -18,3 +18,3 @@ var PORT = server.env.PORT; | ||
return 'Can\'t proxy request to <a href="' + server.target + '">' + server.target + '</a>.'; | ||
return '\nCan\'t proxy request to <a href="' + server.target + '">' + server.target + '</a>.\n<pre><code>\n' + err.message + '\n</code></pre>\n'; | ||
}; |
{ | ||
"name": "hotel", | ||
"version": "0.5.13", | ||
"version": "0.6.0", | ||
"description": "Local domains for everyone and more! ", | ||
"main": "lib", | ||
"bin": "bin/index.js", | ||
"bin": "lib/cli/bin.js", | ||
"preferGlobal": true, | ||
@@ -83,3 +83,3 @@ "engines": { | ||
"escape-html": "^1.0.3", | ||
"husky": "^0.11.3", | ||
"husky": "^0.13.1", | ||
"json-loader": "^0.5.4", | ||
@@ -86,0 +86,0 @@ "lodash.difference": "^4.3.0", |
@@ -9,3 +9,3 @@ # hotel [![Mac/Linux Build Status](https://img.shields.io/travis/typicode/hotel/master.svg?label=Mac%20OSX%20%26%20Linux)](https://travis-ci.org/typicode/hotel) [![Windows Build status](https://img.shields.io/appveyor/ci/typicode/hotel/master.svg?label=Windows)](https://ci.appveyor.com/project/typicode/hotel/branch/master) [![](https://badge.fury.io/js/hotel.svg)](https://www.npmjs.com/package/hotel) | ||
Hotel works great on any OS (OS X, Linux, Windows) and with __all servers :heart:__ | ||
Hotel works great on any OS (OS X, Linux, Windows) and with __all servers :heart:__ | ||
* Node (Express, Webpack) | ||
@@ -184,4 +184,32 @@ * PHP (Laravel, Symfony) | ||
## FAQ | ||
#### Adding `X-Forwarded-*` headers to requests | ||
```sh | ||
hotel add --xfwd 'server-cmd' | ||
``` | ||
Alias `-x` | ||
#### Seting a fixed port | ||
```sh | ||
hotel add --port 3000 'server-cmd $PORT' | ||
``` | ||
Alias `-p` | ||
### Proxying requests to a remote `https` server | ||
```sh | ||
hotel add --change-origin 'https://jsonplaceholder.typicode.com' | ||
``` | ||
Alias `--co` | ||
_When proxying to a `https` server, you may get an error because your local `.dev` domain doesn't match the host defined in the server certificate. With this flag, `host` header is changed to match the target URL._ | ||
## License | ||
MIT - [Typicode](https://github.com/typicode) | ||
MIT - [Typicode :cactus:](https://github.com/typicode) |
@@ -36,6 +36,4 @@ const fs = require('fs') | ||
t.deepEqual( | ||
JSON.parse(fs.readFileSync(file)), | ||
conf | ||
) | ||
const actual = JSON.parse(fs.readFileSync(file)) | ||
t.deepEqual(actual, conf) | ||
}) | ||
@@ -47,3 +45,3 @@ | ||
'add', 'node index.js', | ||
'-d', '/_-Some Project_Name--' | ||
'--dir', '/_-Some Project_Name--' | ||
]) | ||
@@ -61,3 +59,3 @@ | ||
'-n', 'Some Project_Name', | ||
'-d', '/Some Project_Name' | ||
'--dir', '/Some Project_Name' | ||
]) | ||
@@ -74,6 +72,6 @@ | ||
const cmd = 'node index.js' | ||
const n = 'project' | ||
const o = '/some/path/out.log' | ||
const e = ['FOO', 'BAR'] | ||
const p = 3000 | ||
const name = 'project' | ||
const port = 3000 | ||
const out = '/some/path/out.log' | ||
const env = ['FOO', 'BAR'] | ||
@@ -83,6 +81,8 @@ cli([ | ||
'add', cmd, | ||
'-n', n, | ||
'-o', o, | ||
'-e', e[0], e[1], | ||
'-p', p | ||
'-n', name, | ||
'-p', port, | ||
'-o', out, | ||
'-e', env[0], env[1], | ||
'-x', | ||
'--co' | ||
]) | ||
@@ -94,3 +94,3 @@ | ||
cwd: process.cwd(), | ||
out: o, | ||
out: out, | ||
env: { | ||
@@ -100,10 +100,10 @@ PATH: process.env.PATH, | ||
BAR: process.env.BAR, | ||
PORT: p | ||
} | ||
PORT: port | ||
}, | ||
xfwd: true, | ||
changeOrigin: true | ||
} | ||
t.deepEqual( | ||
JSON.parse(fs.readFileSync(file)), | ||
conf | ||
) | ||
const actual = JSON.parse(fs.readFileSync(file)) | ||
t.deepEqual(actual, conf) | ||
}) | ||
@@ -114,3 +114,3 @@ | ||
const cmd = 'node index.js' | ||
const n = 'alias-test' | ||
const name = 'alias-test' | ||
@@ -120,3 +120,3 @@ cli([ | ||
'add', cmd, | ||
'--name', n | ||
'-n', name | ||
]) | ||
@@ -128,3 +128,3 @@ | ||
test('add should support url', (t) => { | ||
test('add should support URL', (t) => { | ||
cli([ | ||
@@ -141,8 +141,26 @@ '', '', | ||
t.deepEqual( | ||
JSON.parse(fs.readFileSync(file)), | ||
conf | ||
) | ||
const actual = JSON.parse(fs.readFileSync(file)) | ||
t.deepEqual(actual, conf) | ||
}) | ||
test('add should support URL and options', (t) => { | ||
cli([ | ||
'', '', | ||
'add', 'http://1.2.3.4', | ||
'-n', 'proxy', | ||
'-x', | ||
'--co' | ||
]) | ||
const file = path.join(serversDir, 'proxy.json') | ||
const conf = { | ||
target: 'http://1.2.3.4', | ||
xfwd: true, | ||
changeOrigin: true | ||
} | ||
const actual = JSON.parse(fs.readFileSync(file)) | ||
t.deepEqual(actual, conf) | ||
}) | ||
/* | ||
@@ -149,0 +167,0 @@ FIXME fails for an unknown reason only in CI, process.chdir doesn't seem to change dir |
@@ -36,3 +36,3 @@ const fs = require('fs') | ||
res.statusCode = 200 | ||
res.end('ok') | ||
res.end(`ok - host: ${req.headers.host}`) | ||
}).listen(4000) | ||
@@ -42,6 +42,7 @@ | ||
servers.add('node index.js', { | ||
n: 'node', | ||
p: 51234, | ||
d: path.join(__dirname, '../fixtures/app'), | ||
o: '/tmp/logs/app.log' | ||
name: 'node', | ||
port: 51234, | ||
dir: path.join(__dirname, '../fixtures/app'), | ||
out: '/tmp/logs/app.log', | ||
xfwd: true | ||
}) | ||
@@ -51,6 +52,6 @@ | ||
servers.add('node index.js', { | ||
n: 'subdomain.node', | ||
p: 51235, | ||
d: path.join(__dirname, '../fixtures/app'), | ||
o: '/tmp/logs/app.log' | ||
name: 'subdomain.node', | ||
port: 51235, | ||
dir: path.join(__dirname, '../fixtures/app'), | ||
out: '/tmp/logs/app.log' | ||
}) | ||
@@ -61,21 +62,31 @@ | ||
servers.add('node index.js', { | ||
n: 'custom-env', | ||
p: 51236, | ||
d: path.join(__dirname, '../fixtures/app'), | ||
o: '/tmp/logs/app.log', | ||
e: ['FOO'] | ||
name: 'custom-env', | ||
port: 51236, | ||
dir: path.join(__dirname, '../fixtures/app'), | ||
out: '/tmp/logs/app.log', | ||
env: ['FOO'] | ||
}) | ||
// Add failing server | ||
servers.add('unknown-cmd', { n: 'failing' }) | ||
servers.add('unknown-cmd', { name: 'failing' }) | ||
// Add server and proxy for testing removal | ||
servers.add('unknown-cmd', { n: 'server-to-remove' }) | ||
servers.add('http://example.com', { n: 'proxy-to-remove' }) | ||
servers.add('unknown-cmd', { name: 'server-to-remove' }) | ||
servers.add('http://example.com', { name: 'proxy-to-remove' }) | ||
// Add URL | ||
servers.add('http://localhost:4000', { n: 'proxy' }) | ||
servers.add('http://localhost:4000', { name: 'proxy' }) | ||
// Add https URL | ||
servers.add('https://jsonplaceholder.typicode.com', { | ||
name: 'working-proxy-with-https-target', | ||
changeOrigin: true | ||
}) | ||
servers.add('https://jsonplaceholder.typicode.com', { | ||
name: 'failing-proxy-with-https-target' | ||
}) | ||
// Add unavailable URL | ||
servers.add('http://localhost:4100', { n: 'unavailable-proxy' }) | ||
servers.add('http://localhost:4100', { name: 'unavailable-proxy' }) | ||
@@ -108,8 +119,12 @@ const group = Group() | ||
test.cb('GET http://node.dev should proxy request', (t) => { | ||
request(app) | ||
.get('/') | ||
.set('Host', 'node.dev') | ||
.expect(200, /Hello World/, t.end) | ||
}) | ||
test.cb( | ||
'GET http://node.dev should proxy request and host should be node.dev', | ||
(t) => { | ||
request(app) | ||
.get('/') | ||
.set('Host', 'node.dev') | ||
.expect(/host: node.dev/) | ||
.expect(200, /Hello World/, t.end) | ||
} | ||
) | ||
@@ -144,14 +159,35 @@ test.cb('GET http://subdomain.node.dev should proxy request', (t) => { | ||
test.cb('GET http://proxy.dev should return 502', (t) => { | ||
test.cb( | ||
'GET http://proxy.dev should return 200 and host should be proxy.dev', | ||
(t) => { | ||
request(app) | ||
.get('/') | ||
.set('Host', 'proxy.dev') | ||
.expect(200, /host: proxy.dev/, t.end) | ||
} | ||
) | ||
test.cb('GET http://node.dev:4000 should proxy to localhost:4000', (t) => { | ||
request(app) | ||
.get('/') | ||
.set('Host', 'proxy.dev') | ||
.set('Host', 'node.dev:4000') | ||
.expect(200, /ok/, t.end) | ||
}) | ||
// | ||
// Test proxy to URLs | ||
// | ||
test.cb('GET http://working-proxy-with-https-target.dev should return 200', (t) => { | ||
request(app) | ||
.get('/') | ||
.set('Host', 'working-proxy-with-https-target.dev') | ||
.expect(200, t.end) | ||
}) | ||
test.cb('GET http://node.dev:4000 should proxy to localhost:4000', (t) => { | ||
test.cb('GET http://failing-proxy-with-https-target.dev should return 502', (t) => { | ||
request(app) | ||
.get('/') | ||
.set('Host', 'node.dev:4000') | ||
.expect(200, /ok/, t.end) | ||
.set('Host', 'failing-proxy-with-https-target.dev') | ||
.expect(502, t.end) | ||
}) | ||
@@ -175,3 +211,3 @@ | ||
if (err) return t.end(err) | ||
t.is(Object.keys(res.body).length, 8, 'got wrong number of servers') | ||
t.is(Object.keys(res.body).length, 10, 'got wrong number of servers') | ||
t.end() | ||
@@ -277,3 +313,3 @@ }) | ||
test.cb('GET / should contain X-FORWARD headers', (t) => { | ||
test.cb('GET node.dev/ should contain X-FORWARD headers', (t) => { | ||
request(app) | ||
@@ -285,2 +321,9 @@ .get('/') | ||
test.cb('GET subdomain.node.dev/ should not contain X-FORWARD headers', (t) => { | ||
request(app) | ||
.get('/') | ||
.set('Host', 'subdomain.node.dev') | ||
.expect(200, /x-forwarded-host: undefined/, t.end) | ||
}) | ||
// | ||
@@ -287,0 +330,0 @@ // Test remove |
@@ -10,3 +10,4 @@ var http = require('http') | ||
process.env.HTTP_PROXY, | ||
'x-forwarded-host: ' + req.headers['x-forwarded-host'] | ||
'x-forwarded-host: ' + req.headers['x-forwarded-host'], | ||
'host: ' + req.headers.host | ||
].join(' ')) | ||
@@ -13,0 +14,0 @@ }).listen(process.env.PORT, '127.0.0.1') |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
1088001
3502
214