Node-http-proxy: 'Can't set headers after they are sent' with express

Created on 4 Feb 2016  路  6Comments  路  Source: http-party/node-http-proxy

my node.js version is 4.2.2

app.js:
var api = require('./routes/api'); app.use('/api', api);

api.js
proxy.on('proxyReq', function(proxyReq, req, res, options) { proxyReq.setHeader('X-Special-Proxy-Header', 'foobar'); }); router.all("/*", function(req, res){ proxy.web(req, res, { target: 'http://dev.lalocal.cn:8080/api' }); });

error:
Error: Can't set headers after they are sent.

Most helpful comment

I ran into this too; it only seems to happen for multipart (chunked) responses. I didn't dig into it too much, but I found a workaround. When you call the proxy method, you pass in an options object -- the third parameter, which contains the target.

Well apparently, if this object contains a 'headers' object, those headers are copied to the proxied request as it's being initialized, and the timing of this copy avoids whatever race condition is causing this failure.

From my code:

              options = { target: target }

              if (result.user) {
                options.headers = {}

                options.headers['x-auth-user-id'] = result.user._id
                options.headers['x-auth-user-username'] = result.user.username
                options.headers['x-auth-user-roles'] = result.user.roles
              }

              return proxy.web(req, res, options)

All 6 comments

Having the same issue under load. My set up is almost identical

I ran into this too; it only seems to happen for multipart (chunked) responses. I didn't dig into it too much, but I found a workaround. When you call the proxy method, you pass in an options object -- the third parameter, which contains the target.

Well apparently, if this object contains a 'headers' object, those headers are copied to the proxied request as it's being initialized, and the timing of this copy avoids whatever race condition is causing this failure.

From my code:

              options = { target: target }

              if (result.user) {
                options.headers = {}

                options.headers['x-auth-user-id'] = result.user._id
                options.headers['x-auth-user-username'] = result.user.username
                options.headers['x-auth-user-roles'] = result.user.roles
              }

              return proxy.web(req, res, options)

+1, happens during bigger load

+1

not sure your exact use case but I ended up writing something that handled this better. Have used it in production for over a year handling multi millions of requests, and am now open sourcing it:

BiFrost

+1

Was this page helpful?
0 / 5 - 0 ratings