node.js node-http-proxy: как избежать исключений с помощью WebSocket при назначении в proxy.web

Используя http-proxy (он же node-http-proxy) в node.js, у меня возникают проблемы с выяснением того, как проксировать веб-сокеты, когда цель определяется динамически (т.е. при обработке запроса).

Глядя на документацию: https://github.com/nodejitsu/node-http-proxy

Вот пример, показывающий возможность установки цели при обработке запроса:

var http = require('http'),
    httpProxy = require('http-proxy');

//
// Create a proxy server with custom application logic
//
var proxy = httpProxy.createProxyServer({});

//
// Create your custom server and just call `proxy.web()` to proxy
// a web request to the target passed in the options
// also you can use `proxy.ws()` to proxy a websockets request
//
var server = http.createServer(function(req, res) {
  // You can define here your custom logic to handle the request
  // and then proxy the request.
  proxy.web(req, res, { target: 'http://127.0.0.1:5060' });
});

console.log("listening on port 5050")
server.listen(5050);

Ниже приведен еще один пример, показывающий поддержку веб-сокетов через proxy.ws(), но он показывает, что цель устанавливается статически, а не зависит от запроса:

//
// Setup our server to proxy standard HTTP requests
//
var proxy = new httpProxy.createProxyServer({
  target: {
    host: 'localhost',
    port: 9015
  }
});
var proxyServer = http.createServer(function (req, res) {
  proxy.web(req, res);
});

//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
proxyServer.on('upgrade', function (req, socket, head) {
  proxy.ws(req, socket, head);
});

proxyServer.listen(8015);

Я взял первый пример и добавил proxyServer.on('upgrade'... proxy.ws()... материал из второго примера, чтобы получить пример, который устанавливает цель при обработке запроса, а также поддерживает веб-сокеты. Веб-страницы HTTP, похоже, работают нормально, но при обработке запроса веб-сокета возникает исключение.

'use strict';
var http = require('http'),
    httpProxy = require('http-proxy');

//
// Create a proxy server with custom application logic
//
var proxy = httpProxy.createProxyServer({});

//
// Create your custom server and just call `proxy.web()` to proxy
// a web request to the target passed in the options
// also you can use `proxy.ws()` to proxy a websockets request
//
var server = http.createServer(function(req, res) {
  // You can define here your custom logic to handle the request
  // and then proxy the request.
  proxy.web(req, res, { target: 'http://127.0.0.1:5060' });
});

//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
server.on('upgrade', function (req, socket, head) {
  proxy.ws(req, socket, head);
});

console.log("listening on port 5050")
server.listen(5050);

Исключение возникает при вызове proxy.ws(req, socket, head):

Error: Must provide a proper URL as target
    at ProxyServer.<anonymous> (...../node_modules/http-proxy/lib/http-proxy/index.js:68:35)
    at Server.<anonymous> (...../poc.js:26:9)  // the location in my sample code of the proxy.ws(req, socket, head) above
    at emitThree (events.js:116:13)
    at Server.emit (events.js:194:7)
    at onParserExecuteCommon (_http_server.js:409:14)
    at HTTPParser.onParserExecute (_http_server.js:377:5)

Код в http-proxy/index.js:68:35 выдает это исключение, если в параметрах нет члена .target или .forward.

Как установить цель для каждого запроса, а также заставить работать веб-сокеты?


person Dave    schedule 07.02.2018    source источник


Ответы (1)


У меня есть ответ. Посмотрев на этот вопрос Конрада и комментарии, а затем поэкспериментировав: -proxyserver-to-multiple-targets

proxy.ws может принимать дополнительный аргумент опций, как и proxy.web.

Вот рабочий код.

'use strict';
var http = require('http'),
    httpProxy = require('http-proxy');

//
// Create a proxy server with custom application logic
//
var proxy = httpProxy.createProxyServer({});

//
// Create your custom server and just call `proxy.web()` to proxy
// a web request to the target passed in the options
// also you can use `proxy.ws()` to proxy a websockets request
//
var server = http.createServer(function(req, res) {
  // You can define here your custom logic to handle the request
  // and then proxy the request.
  proxy.web(req, res, { target: 'http://127.0.0.1:5060' });
});

//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
server.on('upgrade', function (req, socket, head) {
  proxy.ws(req, socket, head, { target: 'ws://127.0.0.1:5060' });
});

console.log("listening on port 5050")
server.listen(5050);
person Dave    schedule 07.02.2018