Skip to content

Latest commit

 

History

History
167 lines (126 loc) · 6.29 KB

File metadata and controls

167 lines (126 loc) · 6.29 KB

Response Interceptor

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

Responses which are compressed with brotli, gzip, deflate and zstd will be decompressed automatically (zstd requires Node.js >= 22.15.0). Response will be made available as buffer which you can manipulate.

Replace text and change http status code

import { createProxyMiddleware, responseInterceptor } from '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
   **/
  on: {
    proxyRes: responseInterceptor(async (responseBuffer, proxyRes, req, res) => {
      res.statusCode = 418; // set different response status code

      const response = responseBuffer.toString('utf8');
      return response.replaceAll('Example', '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()

  on: {
    proxyRes: 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()

  on: {
    proxyRes: 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.

// use jimp library for image manipulation
import { createProxyMiddleware, responseInterceptor } from 'http-proxy-middleware';
import Jimp from 'jimp';

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

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

  on: {
    proxyRes: 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

import { createProxyMiddleware, responseInterceptor } from '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
   **/
  on: {
    proxyRes: 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
      return responseBuffer;
    }),
  },
});