text: /**
   * Module dependencies.
   */
  
  const { StringDecoder } = require('string_decoder');
  const Stream = require('stream');
  const zlib = require('zlib');
  
  /**
   * Buffers response data events and re-emits when they're unzipped.
   *
   * @param {Request} req
   * @param {Response} res
   * @api private
   */
  
  exports.unzip = (req, res) => {
    const unzip = zlib.createUnzip();
    const stream = new Stream();
    let decoder;
  
    // make node responseOnEnd() happy
    stream.req = req;
  
    unzip.on('error', err => {
      if (err && err.code === 'Z_BUF_ERROR') {
        // unexpected end of file is ignored by browsers and curl
        stream.emit('end');
        return;
      }
  
      stream.emit('error', err);
    });
  
    // pipe to unzip
    res.pipe(unzip);
  
    // override `setEncoding` to capture encoding
    res.setEncoding = type => {
      decoder = new StringDecoder(type);
    };
  
    // decode upon decompressing with captured encoding
    unzip.on('data', buf => {
      if (decoder) {
        const str = decoder.write(buf);
        if (str.length > 0) stream.emit('data', str);
      } else {
        stream.emit('data', buf);
      }
    });
  
    unzip.on('end', () => {
      stream.emit('end');
    });
  
    // override `on` to capture data listeners
    const _on = res.on;
    res.on = function(type, fn) {
      if (type === 'data' || type === 'end') {
        stream.on(type, fn.bind(res));
      } else if (type === 'error') {
        stream.on(type, fn.bind(res));
        _on.call(res, type, fn);
      } else {
        _on.call(res, type, fn);
      }
  
      return this;
    };
  };
  