Repository navigation
http2: submit RST_STREAM before emitting 'aborted' - #66314
Conversation
Signed-off-by: lazerg <lazerg2@gmail.com>
|
Review requested:
|
|
Caution AgentScan found account activity patterns that may be consistent with automation. This is a heuristic, not proof that this pull request was opened by an agent or violates policy. AI-assisted contributions are permitted, but automated tooling must not open pull requests without advance approval, and contributors must personally understand, test, verify, and take responsibility for every submitted change. See the AgentScan analysis, AI use policy, and automation policy for additional context. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #66314 +/- ##
==========================================
+ Coverage 90.36% 90.37% +0.01%
==========================================
Files 790 790
Lines 274273 274498 +225
Branches 52513 52569 +56
==========================================
+ Hits 247842 248085 +243
+ Misses 16897 16880 -17
+ Partials 9534 9533 -1
🚀 New features to boost your workflow:
|
|
Landed in 1f26576 |
|
This doesn't land cleanly on v26.x-staging, and would require a manual backport if we want it there |
The first commit stores the code of close(code) before its listeners run. A review and fuzzing found rows that changed against main for callers without the bug. This commit puts them back, and follows node main where a listener throws. - close() keeps its late store of the code too. Another closer that a listener runs (a session teardown, the AbortSignal of the request) does not replace the code at 'close'. - A listener that throws out of close() does not stop the close. The writable ends, the reset goes out and 'close' fires, as in node main (nodejs/node#66314). The error is thrown again after that. - A close() from a listener of a running close() validates its arguments and keeps its callback. Only its code is ignored. - When a listener destroyed the stream, _destroy has queued the reset and close() queues no second one. The reset of close(0) at 'finish' stays. - While close() runs, the stored code does not count as a reset that happened: the streamEnd handlers wait for 'end', and a client gets the response that arrives inside close() on an in-process transport. - _destroy does not keep NGHTTP2_NO_ERROR for a pushed stream, and the teardown of a server session does not replace a stored code.
The first commit stores the code of close(code) before its listeners run. A review and fuzzing found rows that changed against main for callers without the bug. This commit puts them back, and follows node main where a listener throws. - close() keeps its late store of the code too. Another closer that a listener runs (a session teardown, the AbortSignal of the request) does not replace the code at 'close'. - A listener that throws out of close() does not stop the close. The writable ends, the reset goes out and 'close' fires, as in node main (nodejs/node#66314). The error is thrown again after that. - A close() from a listener of a running close() validates its arguments and keeps its callback. Only its code is ignored. - When a listener destroyed the stream, _destroy has queued the reset and close() queues no second one. The reset of close(0) at 'finish' stays. - While close() runs, the stored code does not count as a reset that happened: the streamEnd handlers wait for 'end', and a client gets the response that arrives inside close() on an in-process transport. - _destroy does not keep NGHTTP2_NO_ERROR for a pushed stream, and the teardown of a server session does not replace a stored code.
closeStream() emitted 'aborted' before submitting RST_STREAM. If an 'aborted' listener destroyed the stream (stream.pipeline() does this on its own), _destroy() skipped its RST because the stream was already marked closed, then destroyed the handle, so the later submitRstStream() found no handle and nothing was sent. The peer's stream stayed open until the session closed.
This emits 'aborted' after the RST_STREAM has been submitted.
Fixes: #66306