Repository navigation
http2: enforce maxSessionMemory for client requests - #67361
Open
gabedemesa wants to merge 1 commit into
Open
gabedemesa wants to merge 1 commit into
gabedemesa wants to merge 1 commit into
Conversation
Collaborator
|
Review requested:
|
Contributor
|
Welcome to Node.js, and thank you for your first contribution! Before review, please take a moment to read:
Please make sure every commit is signed off. For a first pull request, GitHub Actions require collaborator approval and Jenkins CI must be started by a collaborator or triager, so an initial wait is normal. |
The documentation for `maxSessionMemory` says new streams are rejected while the limit is exceeded. That was only enforced for streams opened by the peer (`Http2Session::CanAddStream()`); `session.request()` went straight to `nghttp2_submit_request()`. A client whose socket stopped draining could therefore keep submitting requests and queue frames in `outgoing_buffers_` without bound. Check the session memory before submitting a request and fail only that request with `ERR_HTTP2_STREAM_ERROR` (`NGHTTP2_ENHANCE_YOUR_CALM`), leaving the session usable. As with response headers, request bodies queued for flow control are not counted, so large uploads do not block unrelated requests on the same session. Also count the `outgoing_buffers_` descriptors towards the session memory; each queued write costs 32 bytes regardless of its length. Refs: nodejs/undici#6181 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: gdemesa <gdemesa@opengov.com>
gabedemesa
force-pushed
the
http2-client-request-session-memory
branch
from
November 9, 2026 21:52
3cb04f3 to
9e2e2fa
Compare
gabedemesa
marked this pull request as ready for review
November 9, 2026 21:53
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.
The documentation for
maxSessionMemorysays newHttp2Streaminstances are rejected while the limit is exceeded. That was only enforced for streams opened by the peer (Http2Session::CanAddStream()).session.request()went straight tonghttp2_submit_request(), so a client whose socket stopped draining could keep submitting requests and queue frames inoutgoing_buffers_without bound.This checks the session memory in
Http2Session::Request()before submitting and fails only that request withERR_HTTP2_STREAM_ERROR(NGHTTP2_ENHANCE_YOUR_CALM). The session stays usable. As with response headers (#67114), request bodies queued for flow control are not counted, so a large upload does not block unrelated requests on the same session. Theoutgoing_buffers_descriptors (32 bytes per queued write) are now counted towards the session memory.The rejection is signalled by returning
falsefrom the internalrequest()binding rather than a new constant, to avoid adding to the publichttp2.constantsor theNGHTTP2_ERR_*set thattest-http2-client-onconnect-errorsiterates.Verification
30,000 GETs submitted with
maxSessionMemory: 1to a peer that accepts the connection and then pauses its socket (repro from nodejs/undici#6181):outboundQueueSizeENHANCE_YOUR_CALM)All
test/parallel/test-http2-*andtest/sequential/test-http2-*tests pass locally. The newtest-http2-max-session-memory-client-request.jsfails without the change.cpplintis clean; ESLint was not run locally.Not covered
write()backpressure can still queue without bound on that stream (also described in the issue). That is application-level backpressure.Refs: nodejs/undici#6181
🤖 Generated with Claude Code