@@ -195,6 +195,7 @@ const {
195195 kVerifyPeer,
196196 kHeaders,
197197 kSessionId,
198+ kWTSessionClose,
198199 kOwner,
199200 kRemoveSession,
200201 kKeylog,
@@ -270,6 +271,7 @@ const {
270271 onStreamClosedChannel,
271272 onStreamHeadersChannel,
272273 onStreamSessionIdChannel,
274+ onStreamWTSessionCloseChannel,
273275 onStreamTrailersChannel,
274276 onStreamInfoChannel,
275277 onStreamResetChannel,
@@ -310,6 +312,7 @@ const endpointRegistry = new SafeSet();
310312 * webtransport support. If no headers are provided, it has no effect.
311313 * @property {OnHeadersCallback } [onheaders] Callback for incoming initial headers
312314 * @property {OnSessionIdCallback } [onsessionid] Callback for incoming sessionid
315+ * @property {OnWTSessionCloseCallback } [onwtsessionclose] Callback for incoming close capsules
313316 * @property {OnTrailersCallback } [ontrailers] Callback for incoming trailing headers
314317 * @property {OnInfoCallback } [oninfo] Callback for informational (1xx) headers
315318 * @property {OnWantTrailersCallback } [onwanttrailers] Callback fired when the
@@ -473,6 +476,7 @@ const endpointRegistry = new SafeSet();
473476 * @property {OnApplicationCallback } [onapplication] application options callback.
474477 * @property {OnHeadersCallback } [onheaders] Default per-stream initial-headers callback.
475478 * @property {OnSessionIdCallback } [onsessionid] Default perstream initial callback for incoming sessionid.
479+ * @property {OnWTSessionCloseCallback } [onwtsessionclose] Default perstream initial callback for incoming close capsules
476480 * @property {OnTrailersCallback } [ontrailers] Default per-stream trailing-headers callback.
477481 * @property {OnInfoCallback } [oninfo] Default per-stream informational-headers callback.
478482 * @property {OnWantTrailersCallback } [onwanttrailers] Default per-stream
@@ -729,6 +733,15 @@ const endpointRegistry = new SafeSet();
729733 * @returns {void }
730734 */
731735
736+ /**
737+ * Called when session id (e.g. for Webtransport streams) is determined
738+ * @callback OnWTSessionCloseCallback
739+ * @this {QuicStream}
740+ * @param {number } error code from the webtransport session
741+ * @param {string|undefined } error message from the webtransport session
742+ * @returns {void }
743+ */
744+
732745
733746
734747/**
@@ -1025,6 +1038,12 @@ setCallbacks({
10251038 this [ kOwner ] [ kSessionId ] ( sessionId ) ;
10261039 } ,
10271040
1041+ onStreamWTSessionClose ( errorcode , errormessage ) {
1042+ // Called when the stream C++ handle has received a close capsule
1043+ debug ( `stream ${ this [ kOwner ] . id } wtsessionclose callback` , errorcode , errormessage ) ;
1044+ this [ kOwner ] [ kWTSessionClose ] ( errorcode , errormessage ) ;
1045+ } ,
1046+
10281047 onStreamTrailers ( ) {
10291048 // Called when the stream C++ handle is ready to receive trailing headers.
10301049 debug ( 'stream want trailers callback' , this [ kOwner ] ) ;
@@ -1347,6 +1366,7 @@ function applyCallbacks(session, cbs) {
13471366 } ;
13481367 }
13491368 if ( cbs . onsessionid ) session . onsessionid = cbs . onsessionid ;
1369+ if ( cbs . onwtsessionclose ) session . onwtsessionclose = cbs . onwtsessionclose ;
13501370}
13511371
13521372/**
@@ -1607,6 +1627,7 @@ class QuicStream {
16071627 onreset : undefined ,
16081628 onheaders : undefined ,
16091629 onsessionid : undefined ,
1630+ onwtsessionclose : undefined ,
16101631 ontrailers : undefined ,
16111632 oninfo : undefined ,
16121633 onwanttrailers : undefined ,
@@ -1850,6 +1871,26 @@ class QuicStream {
18501871 }
18511872 }
18521873
1874+ /** @type {OnWTSessionCloseCallback } */
1875+ get onwtsessionclose ( ) {
1876+ assertIsQuicStream ( this ) ;
1877+ return this . #inner. onwtsessionclose ;
1878+ }
1879+
1880+ set onwtsessionclose ( fn ) {
1881+ assertIsQuicStream ( this ) ;
1882+ const inner = this . #inner;
1883+ if ( fn === undefined ) {
1884+ inner . onwtsessionclose = undefined ;
1885+ inner . state . wantsWTSessionClose = false ;
1886+ } else {
1887+ console . log ( 'Set wantsWTSessionClose' ) ;
1888+ validateFunction ( fn , 'onwtsessionclose' ) ;
1889+ inner . onwtsessionclose = FunctionPrototypeBind ( fn , this ) ;
1890+ inner . state . wantsWTSessionClose = true ;
1891+ }
1892+ }
1893+
18531894 /** @type {Function|undefined } */
18541895 get oninfo ( ) {
18551896 assertIsQuicStream ( this ) ;
@@ -2614,6 +2655,7 @@ class QuicStream {
26142655 inner . onreset = undefined ;
26152656 inner . onheaders = undefined ;
26162657 inner . onsessionid = undefined ;
2658+ inner . onwtsessionclose = undefined ;
26172659 inner . onerror = undefined ;
26182660 inner . ontrailers = undefined ;
26192661 inner . oninfo = undefined ;
@@ -2728,6 +2770,23 @@ class QuicStream {
27282770 }
27292771 }
27302772
2773+ [ kWTSessionClose ] ( errorcode , errormessage ) {
2774+ if ( this . destroyed ) return ;
2775+ const inner = this . #inner;
2776+ if ( onStreamWTSessionCloseChannel . hasSubscribers ) {
2777+ onStreamWTSessionCloseChannel . publish ( {
2778+ __proto__ : null ,
2779+ stream : this ,
2780+ session : inner . session ,
2781+ errorcode,
2782+ errormessage
2783+ } ) ;
2784+ }
2785+ if ( typeof inner . onwtsessionclose === 'function' ) {
2786+ safeCallbackInvoke ( inner . onwtsessionclose , this , errorcode , errormessage ) ;
2787+ }
2788+ }
2789+
27312790 [ kTrailers ] ( ) {
27322791 if ( this . destroyed ) return ;
27332792 const inner = this . #inner;
@@ -3348,6 +3407,7 @@ class QuicSession {
33483407 headers,
33493408 onheaders,
33503409 onsessionid,
3410+ onwtsessionclose,
33513411 ontrailers,
33523412 oninfo,
33533413 onwanttrailers,
@@ -3405,6 +3465,7 @@ class QuicSession {
34053465 // Set stream callbacks before sending headers to avoid missing events.
34063466 if ( onheaders ) stream . onheaders = onheaders ;
34073467 if ( onsessionid ) stream . onsessionid = onsessionid ;
3468+ if ( onwtsessionclose ) stream . onwtsessionclose = onwtsessionclose ;
34083469 if ( ontrailers ) stream . ontrailers = ontrailers ;
34093470 if ( oninfo ) stream . oninfo = oninfo ;
34103471 if ( onwanttrailers ) stream . onwanttrailers = onwanttrailers ;
@@ -4189,6 +4250,7 @@ class QuicSession {
41894250 if ( scbs ) {
41904251 if ( scbs . onheaders ) stream . onheaders = scbs . onheaders ;
41914252 if ( scbs . onsessionid ) stream . onsessionid = scbs . onsessionid ;
4253+ if ( scbs . onwtsessionclose ) stream . onwtsessionclose = scbs . onwtsessionclose ;
41924254 if ( scbs . ontrailers ) stream . ontrailers = scbs . ontrailers ;
41934255 if ( scbs . oninfo ) stream . oninfo = scbs . oninfo ;
41944256 if ( scbs . onwanttrailers ) stream . onwanttrailers = scbs . onwanttrailers ;
@@ -4567,6 +4629,7 @@ class QuicEndpoint {
45674629 // Stream-level callbacks applied to each incoming stream.
45684630 onheaders,
45694631 onsessionid,
4632+ onwtsessionclose,
45704633 ontrailers,
45714634 oninfo,
45724635 onwanttrailers,
@@ -4593,6 +4656,7 @@ class QuicEndpoint {
45934656 onapplication,
45944657 onheaders,
45954658 onsessionid,
4659+ onwtsessionclose,
45964660 ontrailers,
45974661 oninfo,
45984662 onwanttrailers,
@@ -5329,6 +5393,7 @@ function processSessionOptions(options, config = kEmptyObject) {
53295393 // Stream-level callbacks.
53305394 onheaders,
53315395 onsessionid,
5396+ onwtsessionclose,
53325397 ontrailers,
53335398 oninfo,
53345399 onwanttrailers,
@@ -5451,6 +5516,7 @@ function processSessionOptions(options, config = kEmptyObject) {
54515516 onapplication,
54525517 onheaders,
54535518 onsessionid,
5519+ onwtsessionclose,
54545520 ontrailers,
54555521 oninfo,
54565522 onwanttrailers,
0 commit comments