Skip to content

Commit 698c34a

Browse files
committed
fixup! quic: do not destroy incoming streams that have a consumer
Signed-off-by: Naman Trivedi <trivenay@amazon.com>
1 parent b6ed152 commit 698c34a

6 files changed

Lines changed: 34 additions & 1 deletion

File tree

lib/internal/quic/quic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4139,7 +4139,7 @@ class QuicSession {
41394139
#hasStreamConsumer() {
41404140
if (typeof this.#inner.onstream === 'function') return true;
41414141
if (this[kStreamCallbacks] == null) return false;
4142-
return getQuicSessionState(this).headersSupported === 1;
4142+
return getQuicSessionState(this).streamCallbacksSupported === 1;
41434143
}
41444144

41454145
/**

lib/internal/quic/state.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ const {
7272
IDX_STATE_SESSION_STREAM_OPEN_ALLOWED,
7373
IDX_STATE_SESSION_PRIORITY_SUPPORTED,
7474
IDX_STATE_SESSION_HEADERS_SUPPORTED,
75+
IDX_STATE_SESSION_STREAM_CALLBACKS_SUPPORTED,
7576
IDX_STATE_SESSION_WRAPPED,
7677
IDX_STATE_SESSION_APPLICATION_TYPE,
7778
IDX_STATE_SESSION_NO_ERROR_CODE,
@@ -119,6 +120,7 @@ assert(IDX_STATE_SESSION_HANDSHAKE_CONFIRMED !== undefined);
119120
assert(IDX_STATE_SESSION_STREAM_OPEN_ALLOWED !== undefined);
120121
assert(IDX_STATE_SESSION_PRIORITY_SUPPORTED !== undefined);
121122
assert(IDX_STATE_SESSION_HEADERS_SUPPORTED !== undefined);
123+
assert(IDX_STATE_SESSION_STREAM_CALLBACKS_SUPPORTED !== undefined);
122124
assert(IDX_STATE_SESSION_WRAPPED !== undefined);
123125
assert(IDX_STATE_SESSION_APPLICATION_TYPE !== undefined);
124126
assert(IDX_STATE_SESSION_NO_ERROR_CODE !== undefined);
@@ -493,6 +495,19 @@ class QuicSessionState {
493495
return DataViewPrototypeGetUint8(handle, this.#offset + IDX_STATE_SESSION_HEADERS_SUPPORTED);
494496
}
495497

498+
/**
499+
* Whether the negotiated application dispatches the session-level
500+
* stream callbacks (onheaders et al) for incoming streams.
501+
* Returns 0 (unknown), 1 (supported), or 2 (not supported).
502+
* @type {number}
503+
*/
504+
get streamCallbacksSupported() {
505+
const handle = this.#handle;
506+
if (handle === undefined) return undefined;
507+
return DataViewPrototypeGetUint8(
508+
handle, this.#offset + IDX_STATE_SESSION_STREAM_CALLBACKS_SUPPORTED);
509+
}
510+
496511
/** @type {boolean} */
497512
get isWrapped() {
498513
const handle = this.#handle;

src/quic/application.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,11 @@ class Session::Application : public MemoryRetainer {
210210
// do not support headers should return false (the default).
211211
virtual bool SupportsHeaders() const { return false; }
212212

213+
// True if this application dispatches the session-level stream
214+
// callbacks (onheaders et al) for incoming streams when they are
215+
// registered on the session.
216+
virtual bool SupportsStreamCallbacks() const { return false; }
217+
213218
// Initiates application-level graceful shutdown signaling (e.g.,
214219
// HTTP/3 GOAWAY). Called when Session::Close(GRACEFUL) is invoked.
215220
virtual void BeginShutdown() {}

src/quic/defs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,12 @@ enum class HeadersSupportState : uint8_t {
328328
UNSUPPORTED,
329329
};
330330

331+
enum class StreamCallbacksSupportState : uint8_t {
332+
UNKNOWN,
333+
SUPPORTED,
334+
UNSUPPORTED,
335+
};
336+
331337
enum class PathValidationResult : uint8_t {
332338
SUCCESS = NGTCP2_PATH_VALIDATION_RESULT_SUCCESS,
333339
FAILURE = NGTCP2_PATH_VALIDATION_RESULT_FAILURE,

src/quic/http3.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ class Http3ApplicationImpl final : public Session::Application {
202202

203203
bool SupportsHeaders() const override { return true; }
204204

205+
bool SupportsStreamCallbacks() const override { return true; }
206+
205207
bool is_started() const override { return started_; }
206208

207209
bool Start() override {

src/quic/session.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ uint64_t MaxDatagramPayload(uint64_t max_frame_size) {
136136
V(STREAM_OPEN_ALLOWED, stream_open_allowed, uint8_t) \
137137
V(PRIORITY_SUPPORTED, priority_supported, uint8_t) \
138138
V(HEADERS_SUPPORTED, headers_supported, uint8_t) \
139+
V(STREAM_CALLBACKS_SUPPORTED, stream_callbacks_supported, uint8_t) \
139140
V(WRAPPED, wrapped, uint8_t) \
140141
V(APPLICATION_TYPE, application_type, uint8_t) \
141142
V(NO_ERROR_CODE, no_error_code, error_code) \
@@ -2649,6 +2650,10 @@ void Session::SetApplication(std::unique_ptr<Application> app) {
26492650
impl_->state()->headers_supported = static_cast<uint8_t>(
26502651
app->SupportsHeaders() ? HeadersSupportState::SUPPORTED
26512652
: HeadersSupportState::UNSUPPORTED);
2653+
impl_->state()->stream_callbacks_supported =
2654+
static_cast<uint8_t>(app->SupportsStreamCallbacks()
2655+
? StreamCallbacksSupportState::SUPPORTED
2656+
: StreamCallbacksSupportState::UNSUPPORTED);
26522657
// Surface the application's "no error" and "internal error" codes via
26532658
// session state so that JS-side code (e.g. the stream writer's fail()
26542659
// path) can resolve the right wire code for the negotiated ALPN

0 commit comments

Comments
 (0)