Skip to content

Instantly share code, notes, and snippets.

@kavimaluskam
Created September 12, 2019 09:26
Show Gist options
  • Save kavimaluskam/75e957ce57a01259c5c533f994e82cdd to your computer and use it in GitHub Desktop.
Save kavimaluskam/75e957ce57a01259c5c533f994e82cdd to your computer and use it in GitHub Desktop.
const zlib = require('zlib');
const concatStream = require('concat-stream');
const BufferHelper = require('bufferhelper');
const { debugLogger } = require('../../utils/logger');
/**
* Modify the response
* @param res {Object} The http response
* @param contentEncoding {String} The http header content-encoding: gzip/deflate
* @param callback {Function} Custom modified logic
*/
const modifyResponse = (res, contentEncoding, callback) => {
debugLogger.info('modifyResponse');
debugLogger.info(res.statusCode);
debugLogger.info(contentEncoding);
let unzip, zip;
// Now only deal with the gzip/deflate/undefined content-encoding.
switch (contentEncoding) {
case 'gzip':
unzip = zlib.Gunzip();
zip = zlib.Gzip();
break;
case 'deflate':
unzip = zlib.Inflate();
zip = zlib.Deflate();
break;
}
// The cache response method can be called after the modification.
const _write = res.write;
const _end = res.end;
if (unzip) {
unzip.on('error', e => {
debugLogger.info('Unzip error: ', e);
_end.call(res);
});
handleCompressed(res, _write, _end, unzip, zip, callback);
} else if (!contentEncoding) {
handleUncompressed(res, _write, _end, callback);
} else {
debugLogger.info('Not supported content-encoding: ' + contentEncoding);
}
};
/**
* Handle compressed buffer body
*/
const handleCompressed = (res, _write, _end, unzip, zip, callback) => {
debugLogger.info('handleCompressed');
// The rewrite response method is replaced by unzip stream.
res.write = data => {
unzip.write(data);
};
res.end = () => {
unzip.end();
};
// Concat the unzip stream.
const concatWrite = concatStream(data => {
let body = data.toString();
// Custom modified logic
if (typeof callback === 'function') {
body = callback(body);
}
body = Buffer.from(body);
res.removeHeader('content-length');
// Call the response method and recover the content-encoding.
zip.on('data', chunk => {
_write.call(res, chunk);
});
zip.on('end', () => {
_end.call(res);
});
zip.write(body);
zip.end();
});
unzip.pipe(concatWrite);
};
/**
* Handle Uncompressed buffer body
*/
const handleUncompressed = (res, _write, _end, callback) => {
debugLogger.info('handleUncompressed');
const buffer = new BufferHelper();
// Rewrite response method and get the content.
res.write = data => {
buffer.concat(data);
};
res.end = () => {
let body = buffer.toBuffer().toString();
// Custom modified logic
if (typeof callback === 'function') {
body = callback(body);
}
body = Buffer.from(body);
res.removeHeader('content-length');
// Call the response method
_write.call(res, body);
_end.call(res);
};
};
module.exports = modifyResponse;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment