Skip to content


Subversion checkout URL

You can clone with
Download ZIP


hanging POST requests #180

joeyAghion opened this Issue · 20 comments

I'm using express and trying to proxy certain requests to a different server, as follows (simplified):

var httpProxy = require('http-proxy');
var apiProxy = new httpProxy.RoutingProxy();
app.all('/api/*', function(req, res){
  apiProxy.proxyRequest(req, res, {host: '', port: 9000});

...but POST requests to my server appear to just hang, and never arrive at the target server.

I'm working on a stripped-down-but-working example of this but thought I'd ask first. Has anyone seen this behavior, or are there good examples of node-http-proxy coexisting with express?


I believe your issue may be solved by using the buffer method. A very good explanation can be found here.


@AvianFlu: Thanks for the buffer pointer, but this ended up being caused by express's body-parsing.

Instead of declaring the API route (for proxying) within express routes, I configured it as middleware and used it before express.bodyParser().

Some coffeescript of the solution:

httpProxy = require 'http-proxy'
routingProxy = new httpProxy.RoutingProxy()
apiProxy = (pattern, host, port) ->
  (req, res, next) ->
    if req.url.match(pattern)
      routingProxy.proxyRequest req, res, host: host, port: port

app.configure ->
  @set 'views', 'app/templates'
  # ...
  @use apiProxy /\/api\/.*/, 'localhost', 3000
  @use express.bodyParser()
  # ...

You're correct - express's body parsing turns the request stream into a regular object. The solution is either to buffer it, as I was suggesting, or to deal with the request before the parsing, as you ended up doing. Glad you figured it out!

@AvianFlu AvianFlu closed this
@drewp drewp referenced this issue from a commit in drewp/node-http-proxy
@drewp drewp Address ticket #180 here since that problem is so hard to discover wh…
…en you run into it. If there was an error, people would search for the error text, but there isn't.

I ran into this problem too .. http-proxy@0.8.0, express@2.5.8, connect@1.8.5.

In my case, it turns out that http-proxy's buffer doesn't play well with connect's bodyParser middleware. The buffer is adding listeners for the 'data' and 'end' events to the request object so that it can re-emit them later (on a call to proxyRequest, e.g.). The bodyParser middleware is also adding listeners for the 'data' and 'end' events to the request object but they are never removed. So when re-emitted by the buffer, they're picked up a second time by the bodyParser.

This can result in JSON parse errors and "Can't render headers after they are sent to the client" exceptions (and probably other errors).


For those having issues with this, I found that this information seemed a bit out of date or difficult to implement (too much so for me, at least), compared to using connect-restreamer. That approach is outlined in the middleware example for using the bodyParser:


So, How to solve this problem?


connect-restreamer worked for me. The last thing in my middle-ware is:


Then I have a can do the proxy request normally:

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

app.get('/proxy/', function (req, res) {
  routingProxy.proxyRequest(req, res, {
    host : host,
    port : port

Configuring the proxy as part of middleware before bodyParser (if this is an option for you) also worked for me.

I did not attempt the buffer solution.


Also, simply not using the bodyParser also works (for anyone's future reference).


This thread has helped me. Thanks everyone.


Helpful, Thanks!


For some reason, connect-restreamer didn't fix it for me.

If anyone wants yet another fix, I ended up just calling bodyParser manually. So the proxying worked since bodyParser is not in the middleware. The code looked like:

var connect = require('connect');
var bodyParser = connect.bodyParser();

..."/blah", function(req, res) {
    bodyParser(req, res, function() {
        // Now do something with req.body.thePostData
@imrehorvath imrehorvath referenced this issue from a commit in tombenke/restapi
@imrehorvath imrehorvath Fix issue with the order of middlewares
The order of middlewared does matter. Using the bodyParser before the
httpProxy does break the requests with JSON body.

For more detailed discussion refer to


Man, you saved my life!


Thanks for that solution it works fine
Just configure the proxy as part of middleware before bodyParser


Restreamer works for me. I needed to leave bodyParser because my proxy was conditional upon the contents of the request body. Here is a working example authored by someone else:

@MightyPixel MightyPixel referenced this issue in balderdashy/sails

Explicit body parser #2410


The example from bodyDecoder pointed out by @gdw2 does not work for me. I get

    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)

Using connect-restreamer results in the request continuing to hang.

I am using express instead of connect.

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
    process.nextTick(function () {
      if(req.body) {
        req.emit('data', req.body)

var app = express();

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

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


This may related to this issue however.


@FoxxMD same behavior here


For those in the unfortunate position not being able to rearrange/remove the bodyparser middleware:
I've added the snippet from the example bodyDecode middleware right before I use proxy.web(...) and it just werkz


process.nextTick(function () {
if(req.body) {
   req.emit('data', JSON.stringify(req.body));
proxyServer.web( [...] );

Hope that helps. This was really frustrating.


restreamer didn't work for me.
Only way I was able to get it working with routing is like this: '/api/*', (req, res)->
  r = new http.IncomingMessage()
  r.httpVersion = req.httpVersion
  r.method = req.method
  r.headers = req.headers
  delete r.headers['accept-encoding']
  r.url = req.url
  r.socket = req.socket
  body = JSON.stringify(req.body)
  r.body = body
  size = Buffer.byteLength(body, 'utf8')
  r.headers['content-type'] = "application/json;charset=UTF-8"
  r.headers['content-length'] = size
  buffer = {}
  buffer.pipe = (dest)->
    process.nextTick ->
  proxy.web(r, res, {
    buffer: buffer
    target: "http://localhost:1600"
    proxyTimeout: 5000

@schumacher-m thanks for that for me


@schumacher-m BIG thanks for your tips. It works around the hang issue finally - after a whole day of debugging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.