@@ -191,6 +191,7 @@ const {
191191 kVerifyPeer,
192192 kHeaders,
193193 kSessionId,
194+ kWTSessionClose,
194195 kOwner,
195196 kRemoveSession,
196197 kKeylog,
@@ -266,6 +267,7 @@ const {
266267 onStreamClosedChannel,
267268 onStreamHeadersChannel,
268269 onStreamSessionIdChannel,
270+ onStreamWTSessionCloseChannel,
269271 onStreamTrailersChannel,
270272 onStreamInfoChannel,
271273 onStreamResetChannel,
@@ -306,6 +308,7 @@ const endpointRegistry = new SafeSet();
306308 * webtransport support. If no headers are provided, it has no effect.
307309 * @property {OnHeadersCallback } [onheaders] Callback for incoming initial headers
308310 * @property {OnSessionIdCallback } [onsessionid] Callback for incoming sessionid
311+ * @property {OnWTSessionCloseCallback } [onwtsessionclose] Callback for incoming close capsules
309312 * @property {OnTrailersCallback } [ontrailers] Callback for incoming trailing headers
310313 * @property {OnInfoCallback } [oninfo] Callback for informational (1xx) headers
311314 * @property {OnWantTrailersCallback } [onwanttrailers] Callback fired when the
@@ -469,6 +472,7 @@ const endpointRegistry = new SafeSet();
469472 * @property {OnApplicationCallback } [onapplication] application options callback.
470473 * @property {OnHeadersCallback } [onheaders] Default per-stream initial-headers callback.
471474 * @property {OnSessionIdCallback } [onsessionid] Default perstream initial callback for incoming sessionid.
475+ * @property {OnWTSessionCloseCallback } [onwtsessionclose] Default perstream initial callback for incoming close capsules
472476 * @property {OnTrailersCallback } [ontrailers] Default per-stream trailing-headers callback.
473477 * @property {OnInfoCallback } [oninfo] Default per-stream informational-headers callback.
474478 * @property {OnWantTrailersCallback } [onwanttrailers] Default per-stream
@@ -725,6 +729,15 @@ const endpointRegistry = new SafeSet();
725729 * @returns {void }
726730 */
727731
732+ /**
733+ * Called when session id (e.g. for Webtransport streams) is determined
734+ * @callback OnWTSessionCloseCallback
735+ * @this {QuicStream}
736+ * @param {number } error code from the webtransport session
737+ * @param {string|undefined } error message from the webtransport session
738+ * @returns {void }
739+ */
740+
728741
729742
730743/**
@@ -1021,6 +1034,12 @@ setCallbacks({
10211034 this [ kOwner ] [ kSessionId ] ( sessionId ) ;
10221035 } ,
10231036
1037+ onStreamWTSessionClose ( errorcode , errormessage ) {
1038+ // Called when the stream C++ handle has received a close capsule
1039+ debug ( `stream ${ this [ kOwner ] . id } wtsessionclose callback` , errorcode , errormessage ) ;
1040+ this [ kOwner ] [ kWTSessionClose ] ( errorcode , errormessage ) ;
1041+ } ,
1042+
10241043 onStreamTrailers ( ) {
10251044 // Called when the stream C++ handle is ready to receive trailing headers.
10261045 debug ( 'stream want trailers callback' , this [ kOwner ] ) ;
@@ -1343,6 +1362,7 @@ function applyCallbacks(session, cbs) {
13431362 } ;
13441363 }
13451364 if ( cbs . onsessionid ) session . onsessionid = cbs . onsessionid ;
1365+ if ( cbs . onwtsessionclose ) session . onwtsessionclose = cbs . onwtsessionclose ;
13461366}
13471367
13481368/**
@@ -1603,6 +1623,7 @@ class QuicStream {
16031623 onreset : undefined ,
16041624 onheaders : undefined ,
16051625 onsessionid : undefined ,
1626+ onwtsessionclose : undefined ,
16061627 ontrailers : undefined ,
16071628 oninfo : undefined ,
16081629 onwanttrailers : undefined ,
@@ -1846,6 +1867,26 @@ class QuicStream {
18461867 }
18471868 }
18481869
1870+ /** @type {OnWTSessionCloseCallback } */
1871+ get onwtsessionclose ( ) {
1872+ assertIsQuicStream ( this ) ;
1873+ return this . #inner. onwtsessionclose ;
1874+ }
1875+
1876+ set onwtsessionclose ( fn ) {
1877+ assertIsQuicStream ( this ) ;
1878+ const inner = this . #inner;
1879+ if ( fn === undefined ) {
1880+ inner . onwtsessionclose = undefined ;
1881+ inner . state . wantsWTSessionClose = false ;
1882+ } else {
1883+ console . log ( 'Set wantsWTSessionClose' ) ;
1884+ validateFunction ( fn , 'onwtsessionclose' ) ;
1885+ inner . onwtsessionclose = FunctionPrototypeBind ( fn , this ) ;
1886+ inner . state . wantsWTSessionClose = true ;
1887+ }
1888+ }
1889+
18491890 /** @type {Function|undefined } */
18501891 get oninfo ( ) {
18511892 assertIsQuicStream ( this ) ;
@@ -2610,6 +2651,7 @@ class QuicStream {
26102651 inner . onreset = undefined ;
26112652 inner . onheaders = undefined ;
26122653 inner . onsessionid = undefined ;
2654+ inner . onwtsessionclose = undefined ;
26132655 inner . onerror = undefined ;
26142656 inner . ontrailers = undefined ;
26152657 inner . oninfo = undefined ;
@@ -2724,6 +2766,23 @@ class QuicStream {
27242766 }
27252767 }
27262768
2769+ [ kWTSessionClose ] ( errorcode , errormessage ) {
2770+ if ( this . destroyed ) return ;
2771+ const inner = this . #inner;
2772+ if ( onStreamWTSessionCloseChannel . hasSubscribers ) {
2773+ onStreamWTSessionCloseChannel . publish ( {
2774+ __proto__ : null ,
2775+ stream : this ,
2776+ session : inner . session ,
2777+ errorcode,
2778+ errormessage
2779+ } ) ;
2780+ }
2781+ if ( typeof inner . onwtsessionclose === 'function' ) {
2782+ safeCallbackInvoke ( inner . onwtsessionclose , this , errorcode , errormessage ) ;
2783+ }
2784+ }
2785+
27272786 [ kTrailers ] ( ) {
27282787 if ( this . destroyed ) return ;
27292788 const inner = this . #inner;
@@ -3331,6 +3390,7 @@ class QuicSession {
33313390 headers,
33323391 onheaders,
33333392 onsessionid,
3393+ onwtsessionclose,
33343394 ontrailers,
33353395 oninfo,
33363396 onwanttrailers,
@@ -3388,6 +3448,7 @@ class QuicSession {
33883448 // Set stream callbacks before sending headers to avoid missing events.
33893449 if ( onheaders ) stream . onheaders = onheaders ;
33903450 if ( onsessionid ) stream . onsessionid = onsessionid ;
3451+ if ( onwtsessionclose ) stream . onwtsessionclose = onwtsessionclose ;
33913452 if ( ontrailers ) stream . ontrailers = ontrailers ;
33923453 if ( oninfo ) stream . oninfo = oninfo ;
33933454 if ( onwanttrailers ) stream . onwanttrailers = onwanttrailers ;
@@ -4172,6 +4233,7 @@ class QuicSession {
41724233 if ( scbs ) {
41734234 if ( scbs . onheaders ) stream . onheaders = scbs . onheaders ;
41744235 if ( scbs . onsessionid ) stream . onsessionid = scbs . onsessionid ;
4236+ if ( scbs . onwtsessionclose ) stream . onwtsessionclose = scbs . onwtsessionclose ;
41754237 if ( scbs . ontrailers ) stream . ontrailers = scbs . ontrailers ;
41764238 if ( scbs . oninfo ) stream . oninfo = scbs . oninfo ;
41774239 if ( scbs . onwanttrailers ) stream . onwanttrailers = scbs . onwanttrailers ;
@@ -4550,6 +4612,7 @@ class QuicEndpoint {
45504612 // Stream-level callbacks applied to each incoming stream.
45514613 onheaders,
45524614 onsessionid,
4615+ onwtsessionclose,
45534616 ontrailers,
45544617 oninfo,
45554618 onwanttrailers,
@@ -4576,6 +4639,7 @@ class QuicEndpoint {
45764639 onapplication,
45774640 onheaders,
45784641 onsessionid,
4642+ onwtsessionclose,
45794643 ontrailers,
45804644 oninfo,
45814645 onwanttrailers,
@@ -5312,6 +5376,7 @@ function processSessionOptions(options, config = kEmptyObject) {
53125376 // Stream-level callbacks.
53135377 onheaders,
53145378 onsessionid,
5379+ onwtsessionclose,
53155380 ontrailers,
53165381 oninfo,
53175382 onwanttrailers,
@@ -5434,6 +5499,7 @@ function processSessionOptions(options, config = kEmptyObject) {
54345499 onapplication,
54355500 onheaders,
54365501 onsessionid,
5502+ onwtsessionclose,
54375503 ontrailers,
54385504 oninfo,
54395505 onwanttrailers,
0 commit comments