Как отменить запросы POST и PUT прокси-клиента с помощью node-http-proxy

Я пытаюсь использовать node-http-proxy в качестве обратного прокси-сервера, но не могу заставить работать запросы POST и PUT. Файл server1.js — это обратный прокси-сервер (по крайней мере, для запросов с URL-адресом «/forward-this»), а server2.js — это сервер, который получает проксированные запросы. Объясните пожалуйста, что я делаю не так.

Вот код для server1.js:

// File: server1.js
//

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

httpProxy.createServer(function (req, res, proxy) {
    if (req.method == 'POST' || req.method == 'PUT') {
        req.body = '';

        req.addListener('data', function(chunk) {
            req.body += chunk;
        });

        req.addListener('end', function() {
            processRequest(req, res, proxy);
        });
    } else {
        processRequest(req, res, proxy);
    }

}).listen(8080);

function processRequest(req, res, proxy) {

    if (req.url == '/forward-this') {
        console.log(req.method + ": " + req.url + "=> I'm going to forward this.");

        proxy.proxyRequest(req, res, {
            host: 'localhost',
            port: 8855
        });
    } else {
        console.log(req.method + ": " + req.url + "=> I'm handling this.");

        res.writeHead(200, { "Content-Type": "text/plain" });
        res.write("Server #1 responding to " + req.method + ": " + req.url + "\n");
        res.end();
    }
}

А вот код для server2.js:

// File: server2.js
// 

var http = require('http');

http.createServer(function (req, res, proxy) {
    if (req.method == 'POST' || req.method == 'PUT') {
        req.body = '';

        req.addListener('data', function(chunk) {
            req.body += chunk;
        });

        req.addListener('end', function() {
            processRequest(req, res);
        });
    } else {
        processRequest(req, res);
    }

}).listen(8855);

function processRequest(req, res) {
    console.log(req.method + ": " + req.url + "=> I'm handling this.");

    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.write("Server #2 responding to " + req.method + ': url=' + req.url + '\n');
    res.end();
}

person Jason Roberts    schedule 27.02.2013    source источник


Ответы (3)


http-proxy зависит от событий data и end для запросов POST/PUT. Задержка между моментом, когда server1 получает запрос, и моментом, когда он проксируется, означает, что http-proxy полностью пропускает эти события. Здесь у вас есть два варианта, чтобы заставить это работать правильно: вы можете буферизировать запрос или вы можете использовать маршрутизирующий прокси-сервер. Прокси-сервер маршрутизации кажется здесь наиболее подходящим, поскольку вам нужно проксировать только подмножество запросов. Вот исправленный server1.js:

// File: server1.js
//

var http = require('http');
var httpProxy = require('http-proxy');
var proxy = new httpProxy.RoutingProxy();

http.createServer(function (req, res) {
    if (req.url == '/forward-this') {
        return proxy.proxyRequest(req, res, {
            host: 'localhost',
            port: 8855
        });
    }

    if (req.method == 'POST' || req.method == 'PUT') {
        req.body = '';

        req.addListener('data', function(chunk) {
            req.body += chunk;
        });

        req.addListener('end', function() {
            processRequest(req, res);
        });
    } else {
        processRequest(req, res);
    }

}).listen(8080);

function processRequest(req, res) {
    console.log(req.method + ": " + req.url + "=> I'm handling this.");

    res.writeHead(200, { "Content-Type": "text/plain" });
    res.write("Server #1 responding to " + req.method + ": " + req.url + "\n");
    res.end();
}
person squamos    schedule 28.02.2013
comment
Хотя это старый ответ, чтобы он работал, вы должны заменить var proxy = new httpProxy.RoutingProxy(); на var proxy = httpProxy.createProxyServer({}); - person Saber; 18.08.2017

В дополнение к @squamos

Как написать приложение Node Express, которое обслуживает большинство локальных файлов, но перенаправляет некоторые из них в другой домен?

var proxy = new httpProxy.RoutingProxy();

"Приведенный выше код работает для http-proxy ~0.10.x. С тех пор в библиотеке многое изменилось. Ниже вы можете найти пример для новой версии (на момент написания ~1.0.2)"

var proxy = httpProxy.createProxyServer({});
person Casper    schedule 10.05.2014

Вот мое решение для проксирования POST-запросов. Это не самое идеальное решение, но оно работает и его легко понять.

var request = require('request');

var http = require('http'),
    httpProxy = require('http-proxy'),
    proxy = httpProxy.createProxyServer({});

http.createServer(function(req, res) {
    if (req.method == 'POST') {
        request.post('http://localhost:10500/MyPostRoute',
                     {form: {}},
                     function(err, response, body) {
                         if (! err && res.statusCode == 200) {
                            // Notice I use "res" not "response" for returning response
                            res.writeHead(200, {'Content-Type': "application/json"});
                            res.end(body);
                         }
                         else {
                             res.writeHead(404, {'Content-Type': "application/json"});
                             res.end(JSON.stringify({'Error': err}));
                         }
                     });
    }
    else  if (req.method == 'GET') {
        proxy.web(req, res, { target: 'http://localhost/9000' }, function(err) {
            console.log(err) 
        });
    }

Порты 10500 и 9000 являются произвольными, и в моем коде я динамически назначаю их в зависимости от служб, которые я размещаю. Это не относится к PUT и может быть менее эффективным, потому что я создаю другой ответ вместо того, чтобы манипулировать текущим.

person NuclearPeon    schedule 27.02.2015