UNPKG

koa-even-better-http-proxy

Version:
63 lines (53 loc) 2.02 kB
import zlib from 'zlib'; import { asBuffer } from '../../lib/as'; const isResGzipped = (rspData, res) => rspData?.byteLength > 0 && res.headers['content-encoding'] === 'gzip'; const zipOrUnzip = (method) => (rspData, res) => isResGzipped(rspData, res) ? zlib[method](rspData) : rspData; const maybeUnzipResponse = zipOrUnzip('gunzipSync'); const maybeZipResponse = zipOrUnzip('gzipSync'); const verifyBuffer = (rspd, reject) => { if (Buffer.isBuffer(rspd)) return null; return reject( new Error('userResDecorator should return string or buffer as data') ); }; const updateHeaders = (ctx, rspdBefore, rspdAfter, reject) => { if (!ctx.headerSent) { ctx.set('content-length', rspdAfter.length); } else if (rspdAfter.length !== rspdBefore.length) { const error = '"Content-Length" is already sent,' + 'the length of response data can not be changed'; reject(new Error(error)); } }; export default (container) => { if (container.user.ctx.status === 504) { return Promise.resolve(container); } const resolverFn = container.options.userResDecorator; if (!resolverFn) { return Promise.resolve(container); } const proxyResData = maybeUnzipResponse( container.proxy.resData, container.proxy.res ); const proxyRes = container.proxy.res; const { ctx } = container.user; return Promise.resolve(resolverFn(proxyRes, proxyResData, ctx)).then( (modifiedResData) => new Promise((resolve, reject) => { const rspd = asBuffer(modifiedResData, container.options); verifyBuffer(rspd, reject); updateHeaders(ctx, proxyResData, rspd, reject); // eslint-disable-next-line no-param-reassign container.proxy.resData = maybeZipResponse( rspd, container.proxy.res ); resolve(container); }) ); };