Skip to content

"drain" event listener leak when unpiping to response #135

Open
@zbjornson

Description

@zbjornson

This is sort of a weird scenario, but this test case fails:

  it('should clean up event listeners when res is unpiped to', function (done) {
    var listenerCount
    var server = createServer({ threshold: 0 }, function (req, res) {
      var times = 0
      var int = setInterval(function () {
        var rs = fs.createReadStream('does not exist')
        rs.on('error', function (e) {
          listenerCount = res.listenerCount('drain')
          rs.unpipe(res)
        })
        rs.pipe(res)
        if (times++ > 12) {
          clearInterval(int)
          res.end('hello, world')
        }
      })
    })

    request(server)
      .get('/')
      .set('Accept-Encoding', 'gzip')
      .expect(function () {
        assert.ok(listenerCount < 2)
      })
      .expect(200, done)
  })

I hit this in some code that retries creating a read stream until the source exists. We clean up from our side: rs.on("error", e => { rs.unpipe("res"); }). Seems like compression needs to be cleaning up its listeners when "unpipe" happens.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions