node.jsnode-http-proxy

node http-proxy: async modification of request body


I need to modify the request body asynchronously. Something along the lines of this:

proxy.on('proxyReq', function(proxyReq, req, res, options) {
  if(req.body) {
    new Promise(function(resolve){ 
      setTimeout(function() { // wait for the db to return
        'use strict';
        req.body.text += 'test';
        let bodyData = JSON.stringify(req.body);
        proxyReq.setHeader('Content-Type','application/json');
        proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
        // stream the content
        proxyReq.write(bodyData);
        resolve();
      },1);
    });
  }
});

When I run this I get the error saying cannot modfiy headers once they have been set. Which makes sense.

How can I halt the sending of the request until I'm ready? I've looked at removing various listeners from proxyReq without success..


Solution

  • By looking at the source code @-) it seems like it's not really possible because the proxyReq event is sent and then the code moves on.

    If it would instead wait for a promise, it would be possible (if you'd return that promise as well).

    A minimal fork on this lib could be for example:

    // Enable developers to modify the proxyReq before headers are sent
    proxyReq.on('socket', function(socket) {
      if(server) { server.emit('proxyReq', proxyReq, req, res, options); }
    });
    
    (proxyReq.proxyWait || Promise.resolve())
        .then( ... // rest of the code inside the callback 
    

    And then

    proxy.on('proxyReq', function(proxyReq, req, res, options) {
      if(req.body) {
        proxyReq.proxyWait = new Promise(function(resolve){ 
          setTimeout(function() { ...
    

    But depending on your use case, there might be other solutions as well. For example, consider if it's really necessary that you use this proxy library. It You could alternatively use http directly, where you have all the control on the events and callbacks.