333
schangxiang@126.com
2025-09-19 18966e02fb573c7e2bb0c6426ed792b38b910940
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
'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;
  };
};