Node hangs on POST request when using http-proxy and body-parser with express
Asked Answered
H

3

13

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??

Harrovian answered 14/4, 2015 at 15:54 Comment(1)
Just wondering why you don't just use express middleware instead of http-proxy? You can intercept/modify all requests with middleware.Garlaand
G
4

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(){...});
Gamekeeper answered 10/11, 2021 at 14:33 Comment(2)
Thanks, I can confirm exactly the same issue. Uff, this took a while...Birch
Oh man this took forever to figure out what is up with thatGower
M
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())
Mama answered 10/9, 2015 at 16:31 Comment(1)
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 @chrismckenzieCalcine
H
-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.

Holmen answered 10/9, 2015 at 16:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.