How to cancel POST and PUT requests for a proxy server using node-http-proxy

I am trying to use node-http-proxy as a reverse proxy, but I cannot get POST and PUT requests to work. The server1.js file is the reverse proxy (at least for requests with the / forward-this URL), and server2.js is the server that receives the proxied requests. Please explain what I am doing wrong.

Here is the code for 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(); } } 

And here is the code for 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(); } 
+7
source share
3 answers

http-proxy depends on data and end events for POST / PUT requests. The delay between the time when server1 receives the request and when it is proxied means that the HTTP proxy completely skips these events. You have two options to make this work correctly: you can buffer the request or use a routing proxy . A routing proxy seems to be the most suitable, since you only need to proxy a subset of requests. Here's the revised 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(); } 
+5
source

In addition to @squamos

How to write an express node application that serves most local files but redirects some of them to another domain?

 var proxy = new httpProxy.RoutingProxy(); 

"Http-proxy ~ 0.10.x works on the code. Since then, a lot of things have changed in the library. Below you can find an example for the new version (at the time of writing ~ 1.0.2)"

 var proxy = httpProxy.createProxyServer({}); 
+2
source

Here is my solution for proxying POST requests. This is not the most ideal solution, but it works and is easy to understand.

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

Ports 10500 and 9000 are arbitrary, and in my code I dynamically assign them based on the services that I host. This does not apply to PUT, and it may be less efficient because I am creating a different answer instead of manipulating the current one.

+1
source

All Articles