Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,8 @@ function shouldCompress (req, res) {
### res.flush

This module adds a `res.flush()` method to force the partially-compressed
response to be flushed to the client.
response to be flushed to the client. This function accepts a callback which gets
invoked when the response has been flushed to the client

## Examples

Expand Down
4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ function compression (options) {
var _write = res.write

// flush
res.flush = function flush () {
res.flush = function flush (cb) {
if (stream) {
stream.flush()
stream.flush(cb)
}
}

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.2.0",
"eslint-plugin-standard": "^4.1.0",
"mocha": "^9.2.2",
"mocha": "^10.8.2",
"nyc": "^15.1.0",
"supertest": "^6.2.3"
},
Expand All @@ -41,7 +41,7 @@
},
"scripts": {
"lint": "eslint .",
"test": "mocha --check-leaks --reporter spec",
"test": "mocha --check-leaks --exit --reporter spec",
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test"
}
Expand Down
111 changes: 111 additions & 0 deletions test/compression.js
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,117 @@ describe('compression()', function () {
.end()
})

it('should invoke flush callback when supplied for gzip', function (done) {
var chunks = 0; var callbackInvoked = false
var resp
var server = createServer({ threshold: 0 }, function (req, res) {
resp = res
res.setHeader('Content-Type', 'text/plain')
write()
})

function flushCallback () {
callbackInvoked = true
}

function write () {
chunks++
if (chunks === 20) return resp.end()
if (chunks > 20) return chunks--
Copy link

Copilot AI Apr 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of a decrement operator within the return statement to handle chunk overflow is ambiguous and may lead to unintended behavior. Consider revising the logic with an explicit conditional check to prevent writing beyond the intended chunk count.

Suggested change
if (chunks > 20) return chunks--
if (chunks > 20) {
chunks--;
return;
}

Copilot uses AI. Check for mistakes.
resp.write('..')
resp.flush(flushCallback)
}

request(server)
.get('/')
.set('Accept-Encoding', 'gzip')
.request()
.on('response', function (res) {
assert.equal(res.headers['content-encoding'], 'gzip')
res.on('data', write)
res.on('end', function () {
assert.equal(chunks, 20)
assert.equal(callbackInvoked, true)
done()
})
})
.end()
})

it('should invoke flush callback when supplied for brotli', function (done) {
var chunks = 0; var callbackInvoked = false
var resp
var server = createServer({ threshold: 0 }, function (req, res) {
resp = res
res.setHeader('Content-Type', 'text/plain')
write()
})

function flushCallback () {
callbackInvoked = true
}

function write () {
chunks++
if (chunks === 20) return resp.end()
if (chunks > 20) return chunks--
resp.write('..')
resp.flush(flushCallback)
}

request(server)
.get('/')
.set('Accept-Encoding', 'br')
.request()
.on('response', function (res) {
assert.equal(res.headers['content-encoding'], 'br')
res.on('data', write)
res.on('end', function () {
assert.equal(chunks, 20)
assert.equal(callbackInvoked, true)
done()
})
})
.end()
})

it('should invoke flush callback when supplied for deflate', function (done) {
var chunks = 0; var callbackInvoked = false
var resp
var server = createServer({ threshold: 0 }, function (req, res) {
resp = res
res.setHeader('Content-Type', 'text/plain')
write()
})

function flushCallback () {
callbackInvoked = true
}

function write () {
chunks++
if (chunks === 20) return resp.end()
if (chunks > 20) return chunks--
resp.write('..')
resp.flush(flushCallback)
}

request(server)
.get('/')
.set('Accept-Encoding', 'deflate')
.request()
.on('response', function (res) {
assert.equal(res.headers['content-encoding'], 'deflate')
res.on('data', write)
res.on('end', function () {
assert.equal(chunks, 20)
assert.equal(callbackInvoked, true)
done()
})
})
.end()
})

it('should flush small chunks for deflate', function (done) {
var chunks = 0
var next
Expand Down