Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 298
Matt Foxx Duncan Avatar asked Apr 14 '15 15:04

Matt Foxx Duncan


People also ask

Do you need to install body-parser with Express?

body-parser doesn't have to be installed as a separate package because it is a dependency of express version 4.16. 0+. body-parser isn't a dependency between version 4.0.

What does Bodyparser do express?

Express body-parser is an npm module used to process data sent in an HTTP request body. It provides four express middleware for parsing JSON, Text, URL-encoded, and raw data sets over an HTTP request body. Before the target controller receives an incoming request, these middleware routines handle it.

What is node http proxy?

node-http-proxy is an HTTP programmable proxying library that supports websockets. It is suitable for implementing components such as reverse proxies and load balancers.

How does HTTP request work in node JS?

The HTTP options specify the headers, destination address, and request method type. Next, we use http. request to send the data to the server and await the response. The response is stored in the req variable, and upon error, it is logged into the console.


1 Answers

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())
like image 200
ChrisMcKenzie Avatar answered Sep 21 '22 14:09

ChrisMcKenzie