Skip to content

Commit 0f89eac

Browse files
committed
fix: impl _final method instead hack pipe event
1 parent 8ac1164 commit 0f89eac

File tree

3 files changed

+33
-17
lines changed

3 files changed

+33
-17
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ test/fixtures/chinese-path-test.zip
77
.DS_Store
88
yarn.lock
99
!test/fixtures/symlink/node_modules
10+
pnpm-lock.yaml

lib/zip/uncompress_stream.js

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
// https://github.com/thejoshwolfe/yauzl#no-streaming-unzip-api
44

5+
const debug = require('util').debuglog('compressing/zip/uncompress_stream');
56
const yauzl = require('@eggjs/yauzl');
67
const stream = require('stream');
78
const UncompressBaseStream = require('../base_write_stream');
@@ -38,12 +39,20 @@ class ZipUncompressStream extends UncompressBaseStream {
3839
if (this._zipFileNameEncoding === 'utf-8') {
3940
this._zipFileNameEncoding = 'utf8';
4041
}
42+
this._finalCallback = err => {
43+
if (err) {
44+
debug('finalCallback, error: %j', err);
45+
return this.emit('error', err);
46+
}
47+
this.emit('finish');
48+
};
4149

4250
this[YAUZL_CALLBACK] = this[YAUZL_CALLBACK].bind(this);
4351

4452
const sourceType = utils.sourceType(opts.source);
4553

4654
const yauzlOpts = this._yauzlOpts = Object.assign({}, DEFAULTS, opts.yauzl);
55+
debug('sourceType: %s, yauzlOpts: %j', sourceType, yauzlOpts);
4756
if (sourceType === 'file') {
4857
yauzl.open(opts.source, yauzlOpts, this[YAUZL_CALLBACK]);
4958
return;
@@ -60,27 +69,27 @@ class ZipUncompressStream extends UncompressBaseStream {
6069
.catch(e => this.emit('error', e));
6170
return;
6271
}
63-
64-
this.on('pipe', srcStream => {
65-
srcStream.unpipe(srcStream);
66-
67-
utils.streamToBuffer(srcStream)
68-
.then(buf => {
69-
this._chunks.push(buf);
70-
buf = Buffer.concat(this._chunks);
71-
yauzl.fromBuffer(buf, yauzlOpts, this[YAUZL_CALLBACK]);
72-
})
73-
.catch(e => this.emit('error', e));
74-
});
7572
}
7673

77-
_write(chunk) {
74+
_write(chunk, _encoding, callback) {
7875
// push to _chunks array, this will only happen once, for stream will be unpiped.
7976
this._chunks.push(chunk);
77+
debug('write size: %d, chunks: %d', chunk.length, this._chunks.length);
78+
callback();
79+
}
80+
81+
_final(callback) {
82+
const buf = Buffer.concat(this._chunks);
83+
debug('final, buf size: %d, chunks: %d', buf.length, this._chunks.length);
84+
this._finalCallback = callback;
85+
yauzl.fromBuffer(buf, this._yauzlOpts, this[YAUZL_CALLBACK]);
8086
}
8187

8288
[YAUZL_CALLBACK](err, zipFile) {
83-
if (err) return this.emit('error', err);
89+
if (err) {
90+
debug('yauzl error', err);
91+
return this._finalCallback(err);
92+
}
8493

8594
zipFile.readEntry();
8695

@@ -106,17 +115,22 @@ class ZipUncompressStream extends UncompressBaseStream {
106115

107116
if (type === 'file') {
108117
zipFile.openReadStream(entry, (err, readStream) => {
109-
if (err) return this.emit('error', err);
118+
if (err) {
119+
debug('file, error: %j', err);
120+
return this._finalCallback(err);
121+
}
122+
debug('file, header: %j', header);
110123
this.emit('entry', header, readStream, next);
111124
});
112125
} else { // directory
113126
const placeholder = new stream.Readable({ read() {} });
127+
debug('directory, header: %j', header);
114128
this.emit('entry', header, placeholder, next);
115129
setImmediate(() => placeholder.emit('end'));
116130
}
117131
})
118-
.on('end', () => this.emit('finish'))
119-
.on('error', err => this.emit('error', err));
132+
.on('end', () => this._finalCallback())
133+
.on('error', err => this._finalCallback(err));
120134

121135
function next() {
122136
zipFile.readEntry();

test/zip/uncompress_stream.test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ describe('test/zip/uncompress_stream.test.js', () => {
2121

2222
const uncompressStream = new compressing.zip.UncompressStream();
2323
fs.mkdirSync(destDir, { recursive: true });
24+
2425
pump(sourceStream, uncompressStream, err => {
2526
assert(!err);
2627
const res = dircompare.compareSync(originalDir, path.join(destDir, 'xxx'));

0 commit comments

Comments
 (0)