From 94703492fd215edf283afb65b501f7436e6718c6 Mon Sep 17 00:00:00 2001 From: Julien Fontanet Date: Wed, 30 Mar 2016 17:32:43 +0200 Subject: [PATCH] Use http-proxy for HTTP/ws proxy. --- package.json | 2 +- src/index.js | 43 ++++++++++++++++++++++++++++----------- src/ws-proxy.js | 53 ------------------------------------------------- 3 files changed, 32 insertions(+), 66 deletions(-) delete mode 100644 src/ws-proxy.js diff --git a/package.json b/package.json index f0050ccb0..b863616d8 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "hashy": "~0.4.2", "helmet": "^1.1.0", "highland": "^2.5.1", + "http-proxy": "^1.13.2", "http-server-plus": "^0.6.4", "human-format": "^0.6.0", "is-my-json-valid": "^2.12.2", @@ -114,7 +115,6 @@ "passport-local": "^1.0.0", "promise-toolbox": "^0.3.2", "proxy-agent": "^2.0.0", - "proxy-http-request": "0.1.0", "redis": "^2.0.1", "schema-inspector": "^1.5.1", "semver": "^5.1.0", diff --git a/src/index.js b/src/index.js index aa98ea80c..50cf96411 100644 --- a/src/index.js +++ b/src/index.js @@ -11,10 +11,10 @@ import helmet from 'helmet' import includes from 'lodash.includes' import pick from 'lodash.pick' import proxyConsole from './proxy-console' -import proxyRequest from 'proxy-http-request' import serveStatic from 'serve-static' import startsWith from 'lodash.startswith' import WebSocket from 'ws' +import { createServer as createProxyServer } from 'http-proxy' import {compile as compileJade} from 'jade' import { @@ -33,7 +33,6 @@ import { import * as apiMethods from './api/index' import Api from './api' import WebServer from 'http-server-plus' -import wsProxy from './ws-proxy' import Xo from './xo' import { setup as setupHttpProxy @@ -339,13 +338,30 @@ const setUpProxies = (express, opts, xo) => { return } + const proxy = createProxyServer({ + ignorePath: true + }).on('error', (error) => console.error(error)) + // TODO: sort proxies by descending prefix length. // HTTP request proxy. - forEach(opts, (target, url) => { - express.use(url, (req, res) => { - proxyRequest(target + req.url, req, res) - }) + express.use((req, res, next) => { + const { url } = req + + for (const prefix in opts) { + if (startsWith(url, prefix)) { + const target = opts[prefix] + + console.log('proxy.web', url, target + url.slice(prefix.length)) + proxy.web(req, res, { + target: target + url.slice(prefix.length) + }) + + return + } + } + + next() }) // WebSocket proxy. @@ -355,14 +371,17 @@ const setUpProxies = (express, opts, xo) => { xo.on('stop', () => pFromCallback(cb => webSocketServer.close(cb))) express.on('upgrade', (req, socket, head) => { - const {url} = req + const { url } = req - for (let prefix in opts) { - if (url.lastIndexOf(prefix, 0) !== -1) { - const target = opts[prefix] + url.slice(prefix.length) - webSocketServer.handleUpgrade(req, socket, head, socket => { - wsProxy(socket, target) + for (const prefix in opts) { + if (startsWith(url, prefix)) { + const target = opts[prefix] + + console.log('proxy.ws', url, target + url.slice(prefix.length)) + proxy.ws(req, socket, head, { + target: target + url.slice(prefix.length) }) + return } } diff --git a/src/ws-proxy.js b/src/ws-proxy.js deleted file mode 100644 index eababee28..000000000 --- a/src/ws-proxy.js +++ /dev/null @@ -1,53 +0,0 @@ -import createDebug from 'debug' -import WebSocket from 'ws' - -const debug = createDebug('xo:wsProxy') - -const defaults = { - // Automatically close the client connection when the remote close. - autoClose: true -} - -// Proxy a WebSocket `client` to a remote server which has `url` as -// address. -export default function wsProxy (client, url, opts) { - opts = { - ...defaults, - protocol: client.protocol, - ...opts - } - const autoClose = !!opts.autoClose - delete opts.autoClose - - function onClientSend (error) { - if (error) { - debug('client send error', error) - } - } - function onRemoteSend (error) { - if (error) { - debug('remote send error', error) - } - } - - const remote = new WebSocket(url, opts).once('open', function () { - debug('connected to %s', url) - }).once('close', function () { - debug('remote closed') - - if (autoClose) { - client.close() - } - }).once('error', function (error) { - debug('remote error: %s', error) - }).on('message', function (message) { - client.send(message, onClientSend) - }) - - client.once('close', function () { - debug('client closed') - remote.close() - }).on('message', function (message) { - remote.send(message, onRemoteSend) - }) -}