Skip to content

Latest commit

 

History

History
154 lines (113 loc) · 6.01 KB

response-interceptor.md

File metadata and controls

154 lines (113 loc) · 6.01 KB

Response Interceptor

Intercept responses from upstream with responseInterceptor. (Make sure to set selfHandleResponse: true)

Responses which are compressed with brotli, gzip and deflate will be decompressed automatically. Response will be made available as buffer which you can manipulate.

Replace text and change http status code

const { createProxyMiddleware, responseInterceptor } = require('http-proxy-middleware');

const proxy = createProxyMiddleware({
  target: 'http://www.example.com',
  changeOrigin: true, // for vhosted sites

  /**
   * IMPORTANT: avoid res.end being called automatically
   **/
  selfHandleResponse: true, // res.end() will be called internally by responseInterceptor()

  /**
   * Intercept response and replace 'Hello' with 'Teapot' with 418 http response status code
   **/
  onProxyRes: responseInterceptor(async (responseBuffer, proxyRes, req, res) => {
    res.statusCode = 418; // set different response status code

    const response = responseBuffer.toString('utf8');
    return response.replace('Hello', 'Teapot');
  }),
});

Log request and response

const proxy = createProxyMiddleware({
  target: 'http://www.example.com',
  changeOrigin: true, // for vhosted sites

  selfHandleResponse: true, // res.end() will be called internally by responseInterceptor()

  onProxyRes: responseInterceptor(async (responseBuffer, proxyRes, req, res) => {
    // log original request and proxied request info
    const exchange = `[DEBUG] ${req.method} ${req.path} -> ${proxyRes.req.protocol}//${proxyRes.req.host}${proxyRes.req.path} [${proxyRes.statusCode}]`;
    console.log(exchange); // [DEBUG] GET / -> http://www.example.com [200]

    // log complete response
    const response = responseBuffer.toString('utf8');
    console.log(response); // log response body

    return responseBuffer;
  }),
});

Manipulate JSON responses (application/json)

const proxy = createProxyMiddleware({
  target: 'http://jsonplaceholder.typicode.com',
  changeOrigin: true, // for vhosted sites

  selfHandleResponse: true, // res.end() will be called internally by responseInterceptor()

  onProxyRes: responseInterceptor(async (responseBuffer, proxyRes, req, res) => {
    // detect json responses
    if (proxyRes.headers['content-type'] === 'application/json') {
      let data = JSON.parse(responseBuffer.toString('utf8'));

      // manipulate JSON data here
      data = Object.assign({}, data, { extra: 'foo bar' });

      // return manipulated JSON
      return JSON.stringify(data);
    }

    // return other content-types as-is
    return responseBuffer;
  }),
});

Manipulate image response

Example Lenna image: https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_%28test_image%29.png

Proxy and manipulate image (flip, sepia, pixelate).

Image of Lenna

Check source code on codesandbox.

Some working examples on https://03rjl.sse.codesandbox.io/[relative wikimedia image path]:

You can just use any relative image path from https://upload.wikimedia.org and use the relative image path on https://03rjl.sse.codesandbox.io to see the manipulated image.

const Jimp = require('jimp'); // use jimp library for image manipulation

const proxy = createProxyMiddleware({
  target: 'https://upload.wikimedia.org',
  changeOrigin: true, // for vhosted sites

  selfHandleResponse: true, // res.end() will be called internally by responseInterceptor()

  onProxyRes: responseInterceptor(async (responseBuffer, proxyRes, req, res) => {
    const imageTypes = ['image/png', 'image/jpg', 'image/jpeg', 'image/gif'];

    // detect image responses
    if (imageTypes.includes(proxyRes.headers['content-type'])) {
      try {
        const image = await Jimp.read(responseBuffer);
        image.flip(true, false).sepia().pixelate(5);
        return image.getBufferAsync(Jimp.AUTO);
      } catch (err) {
        console.log('image processing error: ', err);
        return responseBuffer;
      }
    }

    return responseBuffer; // return other content-types as-is
  }),
});

// http://localhost:3000/wikipedia/en/7/7d/Lenna\_%28test_image%29.png

Manipulate response headers

const { createProxyMiddleware, responseInterceptor } = require('http-proxy-middleware');

const proxy = createProxyMiddleware({
  target: 'http://www.example.com',
  changeOrigin: true, // for vhosted sites

  /**
   * IMPORTANT: avoid res.end being called automatically
   **/
  selfHandleResponse: true, // res.end() will be called internally by responseInterceptor()

  /**
   * Intercept response and remove the
   **/
  onProxyRes: responseInterceptor(async (responseBuffer, proxyRes, req, res) => {
    res.removeHeader('content-security-policy'); // Remove the Content Security Policy header
    res.setHeader('HPM-Header', 'Intercepted by HPM'); // Set a new header and value
  }),
});