fix: preserve res.write() return value so backpressure is not swallowed - #67
Open
IanMcNelly wants to merge 1 commit into
Open
fix: preserve res.write() return value so backpressure is not swallowed#67IanMcNelly wants to merge 1 commit into
IanMcNelly wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #66
res.writeis overridden to capture the response body for auditing, but the override callsoldWrite.apply(res, arguments)without returning its result, so every caller getsundefinedinstead of the boolean Node'swrite()contractually returns for backpressure. Anything downstream that honours that return value (if (!res.write(chunk)) await once(res, 'drain'), or a stream's.pipe()) reads theundefinedas "buffer full" and waits for adrainevent that never comes, since the buffer was never actually full, so the response hangs.Fix is one line, return what
oldWrite.applyreturns instead of discarding it:res.write = function (chunk) { chunks.push(Buffer.from(chunk)); - oldWrite.apply(res, arguments); + return oldWrite.apply(res, arguments); };Added a regression test covering both boolean branches, and a CHANGELOG entry under
## [Unreleased]since I didn't want to guess at a version number, feel free to fold that into whatever heading you cut on release.Testing:
npm ci && npm test && npm run test:coverageon Node 16 and 22, 90 passing both times,express-logger.jsat 100/100/100/100 coverage. Also reverted the one-line fix locally to confirm the new test actually fails without it (AssertionError: expected undefined to equal false).Compatibility: non-breaking. Anyone currently ignoring
res.write()'s return value (the common case) is unaffected. Anyone who was checking it and handlingundefinedas "always backpressured" was already broken by this; they'll now get the real signal instead.Scoped to
res.writeonly,res.json/res.endhave the same discarded-return-value issue but only affect chaining, not control flow, so I left them out to keep the scope small