1414 * @private
1515 */
1616
17+ var { finished } = require ( 'node:stream' )
1718var Negotiator = require ( 'negotiator' )
1819var bytes = require ( 'bytes' )
1920var compressible = require ( 'compressible' )
2021var debug = require ( 'debug' ) ( 'compression' )
22+ const isFinished = require ( 'on-finished' ) . isFinished
2123var onHeaders = require ( 'on-headers' )
2224var vary = require ( 'vary' )
2325var zlib = require ( 'zlib' )
@@ -81,9 +83,9 @@ function compression (options) {
8183 var _write = res . write
8284
8385 // flush
84- res . flush = function flush ( ) {
86+ res . flush = function flush ( cb ) {
8587 if ( stream ) {
86- stream . flush ( )
88+ stream . flush ( cb )
8789 }
8890 }
8991
@@ -276,7 +278,12 @@ function compression (options) {
276278 } )
277279
278280 stream . on ( 'data' , function onStreamData ( chunk ) {
281+ if ( isFinished ( res ) ) {
282+ debug ( 'response finished' )
283+ return
284+ }
279285 if ( _write . call ( res , chunk ) === false ) {
286+ debug ( 'pausing compression stream' )
280287 stream . pause ( )
281288 }
282289 } )
@@ -288,6 +295,15 @@ function compression (options) {
288295 _on . call ( res , 'drain' , function onResponseDrain ( ) {
289296 stream . resume ( )
290297 } )
298+
299+ // In case the stream is paused when the response finishes (e.g. because
300+ // the client cuts the connection), its `drain` event may not get emitted.
301+ // The following handler is here to ensure that the stream gets resumed so
302+ // it ends up emitting its `end` event and calling the original
303+ // `res.end()`.
304+ finished ( res , function onResponseFinished ( ) {
305+ stream . resume ( )
306+ } )
291307 } )
292308
293309 next ( )
0 commit comments