express-http-proxy icon indicating copy to clipboard operation
express-http-proxy copied to clipboard

Support for brotli

Open aczekajski opened this issue 6 years ago • 4 comments

Currently, if remote server returns response encoded with brotli algorithm (and sends header content-encoding set to br), the library does nothing to the response which is passed to userResDecorator. In effect, user must manually decompress it and compress it back before returning it from the callback function.

How about adding suport for brotli into express-http-proxy?

Compressing and decompressing with https://www.npmjs.com/package/iltorb package is as simple as doing:

var brotli = require('iltorb');
/* ... */
var decompressedBuffer = brotli.decompressSync(proxyResData);
var compressedBuffer = brotli.compressSync(decompressedBuffer);

I can propose a PR with added support if you approve it.

aczekajski avatar Aug 20 '18 13:08 aczekajski

I can send such PR as well @villadora if you're up to cooperate and get it reviewed/merged. It's an important feature to have because Brotli is getting its popularity and normally things work transparently (the same way this lib does work for gzip)

emirotin avatar Nov 25 '19 13:11 emirotin

I'd be happy to accept a PR for Brotli support that includes tests.

monkpow avatar Nov 25 '19 13:11 monkpow

@monkpow https://github.com/villadora/express-http-proxy/pull/443

emirotin avatar Dec 01 '19 13:12 emirotin

Workaround while we are waiting for @monkpow to merge @emirotin's PR 👯‍♂️

 /**
  * @see https://www.npmjs.com/package/express-http-proxy#proxyreqoptdecorator--supports-promise-form
  * @see https://github.com/villadora/express-http-proxy/blob/master/app/steps/decorateProxyReqOpts.js
  */
proxyReqOptDecorator(proxyReqOpts, srcReq) {
  const BR = 'br';
  const acceptedEncodings = getHeader(proxyReqOpts.headers, 'accept-encoding')?.split(/, ?/);
  if (acceptedEncodings && acceptedEncodings.includes(BR)) {
    pull(acceptedEncodings, BR);
    proxyReqOpts.headers['accept-encoding'] = acceptedEncodings.join(', ');
  }
  return proxyReqOpts;
}


// ...

// utilities

/**
 * NOTE: headers are case insensitive.
 * 
 * @see https://stackoverflow.com/questions/5258977/are-http-headers-case-sensitive
 */
export function getHeader(headers, headerName) {
  headerName = headerName.toLowerCase();
  const key = Object.keys(headers).find(h => h.toLowerCase() === headerName);
  return key && headers[key] || null;
}


Domiii avatar Aug 08 '20 15:08 Domiii