72 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			72 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict';
 | 
						|
 | 
						|
/**
 | 
						|
 * Module dependencies.
 | 
						|
 */
 | 
						|
 | 
						|
const StringDecoder = require('string_decoder').StringDecoder;
 | 
						|
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) 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 ('data' == type || 'end' == type) {
 | 
						|
      stream.on(type, fn);
 | 
						|
    } else if ('error' == type) {
 | 
						|
      stream.on(type, fn);
 | 
						|
      _on.call(res, type, fn);
 | 
						|
    } else {
 | 
						|
      _on.call(res, type, fn);
 | 
						|
    }
 | 
						|
    return this;
 | 
						|
  };
 | 
						|
};
 |