unzip.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. 'use strict';
  2. /**
  3. * Module dependencies.
  4. */
  5. const StringDecoder = require('string_decoder').StringDecoder;
  6. const Stream = require('stream');
  7. const zlib = require('zlib');
  8. /**
  9. * Buffers response data events and re-emits when they're unzipped.
  10. *
  11. * @param {Request} req
  12. * @param {Response} res
  13. * @api private
  14. */
  15. exports.unzip = (req, res) => {
  16. const unzip = zlib.createUnzip();
  17. const stream = new Stream();
  18. let decoder;
  19. // make node responseOnEnd() happy
  20. stream.req = req;
  21. unzip.on('error', err => {
  22. if (err && err.code === 'Z_BUF_ERROR') {
  23. // unexpected end of file is ignored by browsers and curl
  24. stream.emit('end');
  25. return;
  26. }
  27. stream.emit('error', err);
  28. });
  29. // pipe to unzip
  30. res.pipe(unzip);
  31. // override `setEncoding` to capture encoding
  32. res.setEncoding = type => {
  33. decoder = new StringDecoder(type);
  34. };
  35. // decode upon decompressing with captured encoding
  36. unzip.on('data', buf => {
  37. if (decoder) {
  38. const str = decoder.write(buf);
  39. if (str.length) stream.emit('data', str);
  40. } else {
  41. stream.emit('data', buf);
  42. }
  43. });
  44. unzip.on('end', () => {
  45. stream.emit('end');
  46. });
  47. // override `on` to capture data listeners
  48. const _on = res.on;
  49. res.on = function(type, fn) {
  50. if ('data' == type || 'end' == type) {
  51. stream.on(type, fn);
  52. } else if ('error' == type) {
  53. stream.on(type, fn);
  54. _on.call(res, type, fn);
  55. } else {
  56. _on.call(res, type, fn);
  57. }
  58. return this;
  59. };
  60. };