UNPKG

2.32 kBJavaScriptView Raw
1'use strict';
2const {Transform} = require('stream');
3
4module.exports = {
5 download(response, emitter, downloadBodySize) {
6 let downloaded = 0;
7
8 return new Transform({
9 transform(chunk, encoding, callback) {
10 downloaded += chunk.length;
11
12 const percent = downloadBodySize ? downloaded / downloadBodySize : 0;
13
14 // Let `flush()` be responsible for emitting the last event
15 if (percent < 1) {
16 emitter.emit('downloadProgress', {
17 percent,
18 transferred: downloaded,
19 total: downloadBodySize
20 });
21 }
22
23 callback(null, chunk);
24 },
25
26 flush(callback) {
27 emitter.emit('downloadProgress', {
28 percent: 1,
29 transferred: downloaded,
30 total: downloadBodySize
31 });
32
33 callback();
34 }
35 });
36 },
37
38 upload(request, emitter, uploadBodySize) {
39 const uploadEventFrequency = 150;
40 let uploaded = 0;
41 let progressInterval;
42
43 emitter.emit('uploadProgress', {
44 percent: 0,
45 transferred: 0,
46 total: uploadBodySize
47 });
48
49 request.once('error', () => {
50 clearInterval(progressInterval);
51 });
52
53 request.once('response', () => {
54 clearInterval(progressInterval);
55
56 emitter.emit('uploadProgress', {
57 percent: 1,
58 transferred: uploaded,
59 total: uploadBodySize
60 });
61 });
62
63 request.once('socket', socket => {
64 const onSocketConnect = () => {
65 progressInterval = setInterval(() => {
66 const lastUploaded = uploaded;
67 /* istanbul ignore next: see #490 (occurs randomly!) */
68 const headersSize = request._header ? Buffer.byteLength(request._header) : 0;
69 uploaded = socket.bytesWritten - headersSize;
70
71 // Don't emit events with unchanged progress and
72 // prevent last event from being emitted, because
73 // it's emitted when `response` is emitted
74 if (uploaded === lastUploaded || uploaded === uploadBodySize) {
75 return;
76 }
77
78 emitter.emit('uploadProgress', {
79 percent: uploadBodySize ? uploaded / uploadBodySize : 0,
80 transferred: uploaded,
81 total: uploadBodySize
82 });
83 }, uploadEventFrequency);
84 };
85
86 /* istanbul ignore next: hard to test */
87 if (socket.connecting) {
88 socket.once('connect', onSocketConnect);
89 } else if (socket.writable) {
90 // The socket is being reused from pool,
91 // so the connect event will not be emitted
92 onSocketConnect();
93 }
94 });
95 }
96};