express-http-proxy-preintercept

http proxy middleware for express

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
express-http-proxy-preintercept
0.9.16 years ago6 years agoMinified + gzip package size for express-http-proxy-preintercept in KB

Readme

express-http-proxy NPM version Build Status Dependency Status
Express proxy middleware to forward request to another host and pass response back

Install

$ npm install express-http-proxy --save

Usage

proxy(host, options);

To proxy URLS starting with '/proxy' to the host 'www.google.com':
var proxy = require('express-http-proxy');

var app = require('express')();

app.use('/proxy', proxy('www.google.com'));

Options

forwardPath

The ``forwardPath`` option allows you to modify the path prior to proxying the request.
var proxy = require('express-http-proxy');

var app = require('express')();

app.use('/proxy', proxy('www.google.com', {
  forwardPath: function(req, res) {
    return require('url').parse(req.url).path;
  }
}));

forwardPathAsync

The ``forwardPathAsync`` options allows you to modify the path asyncronously prior to proxying the request, using Promises.
app.use(proxy('httpbin.org', {
  forwardPathAsync: function() {
    return new Promise(function(resolve, reject) {
      // ...
      // eventually
      resolve( /* your resolved eorwardPath as string */ )
    });
  }
}));

filter

The ``filter`` option can be used to limit what requests are proxied. For example, if you only want to proxy get request
app.use('/proxy', proxy('www.google.com', {
  filter: function(req, res) {
     return req.method == 'GET';
  },
  forwardPath: function(req, res) {
    return require('url').parse(req.url).path;
  }
}));

intercept

You can intercept the response before sending it back to the client.
app.use('/proxy', proxy('www.google.com', {
  intercept: function(rsp, data, req, res, callback) {
    // rsp - original response from the target
    data = JSON.parse(data.toString('utf8'));
    callback(null, JSON.stringify(data));
  }
}));

preIntercept

Similar to intercept, but is executed before the request was actually sent.
Can be used to modify headers, while intercept stage is too late for this.
app.use('/proxy', proxy('www.google.com', {
  preIntercept: function(res) {
    var cookie = res.headers['set-cookie'];
    if (cookie) {
      // Make HTTPS -> HTTP proxying work correctly.
      if (Array.isArray(cookie)) {
        res.headers['set-cookie'] = cookie.map(function(item) {
          item.replace('secure; ', '');
        });
      }
      delete res.headers['strict-ransport-security'];
    }
  }
}));

decorateRequest

You can change the request options before it is sent to the target.
app.use('/proxy', proxy('www.google.com', {
  decorateRequest: function(proxyReq, originalReq) {
    // you can update headers
    proxyReq.headers['Content-Type'] = 'text/html';
    // you can change the method
    proxyReq.method = 'GET';
    // you can munge the bodyContent.
    proxyReq.bodyContent = proxyReq.bodyContent.replace(/losing/, 'winning!');
    return proxyReq;
  }
}));

preserveHostHdr

You can copy the host HTTP header to the proxied express server using the preserveHostHdr option.
app.use('/proxy', proxy('www.google.com', {
  preserveHostHdr: true
}));

reqAsBuffer

Note: this is an experimental feature. ymmv
The ``reqAsBuffer`` option allows you to ensure the req body is encoded as a Node ``Buffer`` when sending a proxied request. Any value for this is truthy.
This defaults to to false in order to preserve legacy behavior. Note that the value of ``reqBodyEnconding`` is used as the encoding when coercing strings (and stringified JSON) to Buffer.
app.use('/proxy', proxy('www.google.com', {
  reqAsBuffer: true
}));

reqBodyEncoding

Encoding used to decode request body. Defaults to ``utf-8``.
Use ``null`` to preserve as Buffer when proxied request body is a Buffer. (e.g image upload) Accept any values supported by raw-body.
The same encoding is used in the intercept method.
app.use('/post', proxy('httpbin.org', {
  reqBodyEncoding: null
}));

timeout

By default, node does not express a timeout on connections. Use timeout option to impose a specific timeout. Timed-out requests will respond with 504 status code and a X-Timeout-Reason header.
app.use('/', proxy('httpbin.org', {
  timeout: 2000  // in milliseconds, two seconds
}));

Questions

Q: Can it support https proxy?

The library will use https if the provided path has 'https://' or ':443'. You can use decorateRequest to ammend any auth or challenge headers required to succeed https.
Here is an older answer about using the https-proxy-agent package. It may be useful if the included functionality in ``http-express-proxy`` does not solve your use case.
A: Yes, you can use the 'https-proxy-agent' package. Something like this:
var corporateProxyServer = process.env.HTTP_PROXY || process.env.http_proxy || process.env.HTTPS_PROXY || process.env.https_proxy;

if (corporateProxyServer) {
  corporateProxyAgent = new HttpsProxyAgent(corporateProxyServer);
}

Then inside the decorateRequest method, add the agent to the request:
req.agent = corporateProxyAgent;

Release Notes

| Release | Notes | | --- | --- | | 0.9.1 | Documentation updates. Set 'Accept-Encoding' header to match bodyEncoding. | | 0.9.0 | Better handling for request body when body is JSON. | | 0.8.0 | Features: add forwardPathAsync option
Updates: modernize dependencies
Fixes: Exceptions parsing proxied response causes error: Can't set headers after they are sent. (#111)
If client request aborts, proxied request is aborted too (#107) | | 0.7.4 | Move jscs to devDependencies to avoid conflict with nsp. | | 0.7.3 | Adds a timeout option. Code organization and small bug fixes. | | 0.7.2 | Collecting many minor documentation and test improvements. | | 0.4.0 | Signature of intercept callback changed from function(data, req, res, callback) to function(rsp, data, req, res, callback) where rsp is the original response from the target |

Licence

MIT