22
33// https://github.com/thejoshwolfe/yauzl#no-streaming-unzip-api
44
5+ const debug = require ( 'util' ) . debuglog ( 'compressing/zip/uncompress_stream' ) ;
56const yauzl = require ( '@eggjs/yauzl' ) ;
67const stream = require ( 'stream' ) ;
78const 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 ( ) ;
0 commit comments