12

I've also posted this to the relevant issue on http-proxy.

I'm using http-proxy with express so I can intercept requests between my client and api in order to add some cookies for authentication.

In order to authenticate the client must send a POST request with x-www-form-urlencoded as the the content-type. So I am using body-parser middleware to parse the request body so I can insert data in the request.

http-proxy has a problem with using body-parser supposedly because it parses the body as a stream and never closes it so the proxy never never completes the request.

There is a solution in the http-proxy examples that "re-streams" the request after it has been parsed which I have tried to use. I have also tried to use the connect-restreamer solution in the same issue with no luck.

My code looks like this

var express = require('express'),
    bodyParser = require('body-parser'),
    httpProxy = require('http-proxy');

var proxy = httpProxy.createProxyServer({changeOrigin: true});
var restreamer = function (){
  return function (req, res, next) { //restreame
    req.removeAllListeners('data')
    req.removeAllListeners('end')
    next()
    process.nextTick(function () {
      if(req.body) {
        req.emit('data', req.body) //error gets thrown here
      }
      req.emit('end')
    })
  }
}

var app = express();

app.use(bodyParser.urlencoded({extended: false, type: 'application/x-www-form-urlencoded'}));
app.use(restreamer());

app.all("/api/*", function(req, res) {
    //modifying req.body here
    //
    proxy.web(req, res, { target: 'http://urlToServer'});
});

app.listen(8080);

and I receive this error

/Code/project/node_modules/http-proxy/lib/http-proxy/index.js:119
throw err;
      ^
Error: write after end
    at ClientRequest.OutgoingMessage.write (_http_outgoing.js:413:15)
    at IncomingMessage.ondata (_stream_readable.js:540:20)
    at IncomingMessage.emit (events.js:107:17)
    at /Code/project/lib/server.js:46:25
    at process._tickCallback (node.js:355:11)

I have tried to debug the flow but am grasping for straws. Any suggestions please??

Matt Foxx Duncan
  • 2,074
  • 3
  • 23
  • 38
  • Just wondering why you don't just use express middleware instead of http-proxy? You can intercept/modify all requests with middleware. – jfriend00 Sep 10 '15 at 04:27

3 Answers3

3

I was experiencing this issue and I was not able to get restreaming to work. Here is the solution I came to albeit crude and may not be acceptable for your project.

I ended up moving the body-parser middleware on to the route itself and not be route middleware since my project only had a couple routes and the reset were going through my http-proxy middleware.

so instead of this:

router.use(bodyParser.json());

router.get('/', function(){...});

router.use(httpProxy());

I did this:

router.get('/', bodyParser.json(), function(){...})

router.use(httpProxy())
ChrisMcKenzie
  • 367
  • 1
  • 3
  • 12
  • This helped me. I was stuck in this issue for almost 2 days. Went over multiple posts, blogs and articles on the web but could not get my issue resolved. Finally I tried this and I see my response coming back from the proxied server. Thanks @chrismckenzie – Akash_Kumar May 31 '20 at 07:27
1

I was facing this same issue with http-proxy-middleware. After reading @ChrisMckenzie's answer, I decided to simply move the body parser middleware to after the proxy middleware.

so instead of this:

router.use(bodyParser.json());

router.get('/', function(){...});

router.use(httpProxy());

I did this:

router.use(httpProxy());

router.use(bodyParser.json());

router.get('/', function(){...});
lwdthe1
  • 1,001
  • 1
  • 16
  • 16
-4

http-proxy is notoriously bad at handling POST bodies, especially in the latest versions of Node; and middleware hacks don't always work with all POST requests. I suggest you use a dedicated http proxy engine like the one in NGINX or HAPROXY, those work the best.

Victor Martinez
  • 980
  • 1
  • 8
  • 14