1 | 'use strict';
|
2 | const {Transform} = require('stream');
|
3 | const decompressResponse = require('decompress-response');
|
4 | const is = require('@sindresorhus/is');
|
5 | const mimicResponse = require('mimic-response');
|
6 |
|
7 | module.exports = (response, options, emitter, redirects) => {
|
8 | const downloadBodySize = Number(response.headers['content-length']) || null;
|
9 | let downloaded = 0;
|
10 |
|
11 | const progressStream = new Transform({
|
12 | transform(chunk, encoding, callback) {
|
13 | downloaded += chunk.length;
|
14 |
|
15 | const percent = downloadBodySize ? downloaded / downloadBodySize : 0;
|
16 |
|
17 |
|
18 | if (percent < 1) {
|
19 | emitter.emit('downloadProgress', {
|
20 | percent,
|
21 | transferred: downloaded,
|
22 | total: downloadBodySize
|
23 | });
|
24 | }
|
25 |
|
26 | callback(null, chunk);
|
27 | },
|
28 |
|
29 | flush(callback) {
|
30 | emitter.emit('downloadProgress', {
|
31 | percent: 1,
|
32 | transferred: downloaded,
|
33 | total: downloadBodySize
|
34 | });
|
35 |
|
36 | callback();
|
37 | }
|
38 | });
|
39 |
|
40 | mimicResponse(response, progressStream);
|
41 | progressStream.redirectUrls = redirects;
|
42 |
|
43 | const newResponse = options.decompress === true &&
|
44 | is.function(decompressResponse) &&
|
45 | options.method !== 'HEAD' ? decompressResponse(progressStream) : progressStream;
|
46 |
|
47 | if (!options.decompress && ['gzip', 'deflate'].includes(response.headers['content-encoding'])) {
|
48 | options.encoding = null;
|
49 | }
|
50 |
|
51 | emitter.emit('response', newResponse);
|
52 |
|
53 | emitter.emit('downloadProgress', {
|
54 | percent: 0,
|
55 | transferred: 0,
|
56 | total: downloadBodySize
|
57 | });
|
58 |
|
59 | response.pipe(progressStream);
|
60 | };
|