Use http-proxy for HTTP/ws proxy.

This commit is contained in:
Julien Fontanet 2016-03-30 17:32:43 +02:00
parent df78117617
commit 94703492fd
3 changed files with 32 additions and 66 deletions

View File

@ -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",

View File

@ -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
}
}

View File

@ -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)
})
}