@fails-components/webtransport 1.0.8 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/dist/lib/client.d.ts.map +1 -0
  2. package/dist/{main/lib → lib}/dom.d.ts +10 -2
  3. package/dist/lib/dom.d.ts.map +1 -0
  4. package/dist/lib/error.d.ts.map +1 -0
  5. package/dist/{main/lib → lib}/features.d.ts.map +1 -1
  6. package/dist/{main/lib → lib}/http2/browser/browser.d.ts +2 -0
  7. package/dist/lib/http2/browser/browser.d.ts.map +1 -0
  8. package/dist/lib/http2/browser/browserparser.d.ts.map +1 -0
  9. package/dist/{main/lib → lib}/http2/flowcontroller.d.ts +1 -1
  10. package/dist/lib/http2/flowcontroller.d.ts.map +1 -0
  11. package/dist/{main/lib → lib}/http2/node/capsuleparser.d.ts +1 -1
  12. package/dist/lib/http2/node/capsuleparser.d.ts.map +1 -0
  13. package/dist/{main/lib → lib}/http2/node/client.d.ts +2 -0
  14. package/dist/lib/http2/node/client.d.ts.map +1 -0
  15. package/dist/{main/test → lib/http2/node}/index.d.ts.map +1 -1
  16. package/dist/{main/lib → lib}/http2/node/server.d.ts +3 -0
  17. package/dist/lib/http2/node/server.d.ts.map +1 -0
  18. package/dist/{main/lib → lib}/http2/node/websocketparser.d.ts +4 -2
  19. package/dist/lib/http2/node/websocketparser.d.ts.map +1 -0
  20. package/dist/{main/lib → lib}/http2/parserbase.d.ts +26 -9
  21. package/dist/lib/http2/parserbase.d.ts.map +1 -0
  22. package/dist/lib/http2/parserbasehttp2.d.ts.map +1 -0
  23. package/dist/{main/lib → lib}/http2/session.d.ts +43 -6
  24. package/dist/lib/http2/session.d.ts.map +1 -0
  25. package/dist/{main/lib → lib}/http2/stream.d.ts +29 -7
  26. package/dist/lib/http2/stream.d.ts.map +1 -0
  27. package/dist/lib/http2/streamidmanager.d.ts +72 -0
  28. package/dist/lib/http2/streamidmanager.d.ts.map +1 -0
  29. package/dist/lib/http2/websocketcommon.d.ts.map +1 -0
  30. package/dist/lib/index.browser.d.ts.map +1 -0
  31. package/dist/lib/index.node.d.ts.map +1 -0
  32. package/dist/lib/server.d.ts.map +1 -0
  33. package/dist/{main/lib → lib}/session.d.ts +10 -3
  34. package/dist/lib/session.d.ts.map +1 -0
  35. package/dist/lib/stream.d.ts.map +1 -0
  36. package/dist/{main/lib → lib}/types.d.ts +26 -4
  37. package/dist/lib/types.d.ts.map +1 -0
  38. package/dist/lib/utils.d.ts.map +1 -0
  39. package/dist/lib/webstreams.browser.d.ts.map +1 -0
  40. package/dist/lib/webstreams.d.ts.map +1 -0
  41. package/dist/{main/lib → lib}/webtransport.browser.d.ts +12 -2
  42. package/dist/lib/webtransport.browser.d.ts.map +1 -0
  43. package/dist/lib/webtransport.node.d.ts.map +1 -0
  44. package/dist/{main/lib → lib}/webtransportbase.d.ts +14 -2
  45. package/dist/lib/webtransportbase.d.ts.map +1 -0
  46. package/lib/dom.ts +12 -2
  47. package/lib/http2/browser/browser.js +12 -3
  48. package/lib/http2/browser/browserparser.js +36 -36
  49. package/lib/http2/flowcontroller.js +2 -2
  50. package/lib/http2/node/capsuleparser.js +58 -51
  51. package/lib/http2/node/client.js +12 -3
  52. package/lib/http2/node/server.js +53 -16
  53. package/lib/http2/node/websocketparser.js +69 -59
  54. package/lib/http2/parserbase.js +87 -12
  55. package/lib/http2/session.js +109 -34
  56. package/lib/http2/stream.js +65 -10
  57. package/lib/http2/streamidmanager.js +316 -0
  58. package/lib/session.js +31 -5
  59. package/lib/types.ts +20 -4
  60. package/lib/webtransport.browser.js +14 -4
  61. package/lib/webtransportbase.js +14 -4
  62. package/package.json +1 -1
  63. package/readme.md +4 -3
  64. package/test/fixtures/certificate.js +1 -2
  65. package/test/fixtures/server.js +112 -7
  66. package/test/stream-limits.spec.js +247 -0
  67. package/tsconfig.json +2 -7
  68. package/dist/main/lib/client.d.ts.map +0 -1
  69. package/dist/main/lib/dom.d.ts.map +0 -1
  70. package/dist/main/lib/error.d.ts.map +0 -1
  71. package/dist/main/lib/http2/browser/browser.d.ts.map +0 -1
  72. package/dist/main/lib/http2/browser/browserparser.d.ts.map +0 -1
  73. package/dist/main/lib/http2/flowcontroller.d.ts.map +0 -1
  74. package/dist/main/lib/http2/node/capsuleparser.d.ts.map +0 -1
  75. package/dist/main/lib/http2/node/client.d.ts.map +0 -1
  76. package/dist/main/lib/http2/node/index.d.ts.map +0 -1
  77. package/dist/main/lib/http2/node/server.d.ts.map +0 -1
  78. package/dist/main/lib/http2/node/websocketparser.d.ts.map +0 -1
  79. package/dist/main/lib/http2/parserbase.d.ts.map +0 -1
  80. package/dist/main/lib/http2/parserbasehttp2.d.ts.map +0 -1
  81. package/dist/main/lib/http2/session.d.ts.map +0 -1
  82. package/dist/main/lib/http2/stream.d.ts.map +0 -1
  83. package/dist/main/lib/http2/websocketcommon.d.ts.map +0 -1
  84. package/dist/main/lib/index.browser.d.ts.map +0 -1
  85. package/dist/main/lib/index.node.d.ts.map +0 -1
  86. package/dist/main/lib/server.d.ts.map +0 -1
  87. package/dist/main/lib/session.d.ts.map +0 -1
  88. package/dist/main/lib/stream.d.ts.map +0 -1
  89. package/dist/main/lib/types.d.ts.map +0 -1
  90. package/dist/main/lib/utils.d.ts.map +0 -1
  91. package/dist/main/lib/webstreams.browser.d.ts.map +0 -1
  92. package/dist/main/lib/webstreams.d.ts.map +0 -1
  93. package/dist/main/lib/webtransport.browser.d.ts.map +0 -1
  94. package/dist/main/lib/webtransport.node.d.ts.map +0 -1
  95. package/dist/main/lib/webtransportbase.d.ts.map +0 -1
  96. package/dist/main/test/bidirectional-streams.spec.d.ts +0 -5
  97. package/dist/main/test/bidirectional-streams.spec.d.ts.map +0 -1
  98. package/dist/main/test/datagrams.spec.d.ts +0 -5
  99. package/dist/main/test/datagrams.spec.d.ts.map +0 -1
  100. package/dist/main/test/fixtures/certificate.d.ts +0 -21
  101. package/dist/main/test/fixtures/certificate.d.ts.map +0 -1
  102. package/dist/main/test/fixtures/chai.d.ts +0 -2
  103. package/dist/main/test/fixtures/chai.d.ts.map +0 -1
  104. package/dist/main/test/fixtures/known-bytes.d.ts +0 -8
  105. package/dist/main/test/fixtures/known-bytes.d.ts.map +0 -1
  106. package/dist/main/test/fixtures/p-timeout.d.ts +0 -8
  107. package/dist/main/test/fixtures/p-timeout.d.ts.map +0 -1
  108. package/dist/main/test/fixtures/read-cert-hash.d.ts +0 -6
  109. package/dist/main/test/fixtures/read-cert-hash.d.ts.map +0 -1
  110. package/dist/main/test/fixtures/read-stream.d.ts +0 -18
  111. package/dist/main/test/fixtures/read-stream.d.ts.map +0 -1
  112. package/dist/main/test/fixtures/reader-value.d.ts +0 -21
  113. package/dist/main/test/fixtures/reader-value.d.ts.map +0 -1
  114. package/dist/main/test/fixtures/server.d.ts +0 -5
  115. package/dist/main/test/fixtures/server.d.ts.map +0 -1
  116. package/dist/main/test/fixtures/webtransport.browser.d.ts +0 -4
  117. package/dist/main/test/fixtures/webtransport.browser.d.ts.map +0 -1
  118. package/dist/main/test/fixtures/webtransport.d.ts +0 -3
  119. package/dist/main/test/fixtures/webtransport.d.ts.map +0 -1
  120. package/dist/main/test/fixtures/write-stream.d.ts +0 -10
  121. package/dist/main/test/fixtures/write-stream.d.ts.map +0 -1
  122. package/dist/main/test/index.d.ts +0 -2
  123. package/dist/main/test/session.spec.d.ts +0 -5
  124. package/dist/main/test/session.spec.d.ts.map +0 -1
  125. package/dist/main/test/unidirectional-streams.spec.d.ts +0 -2
  126. package/dist/main/test/unidirectional-streams.spec.d.ts.map +0 -1
  127. package/dist/main/tsconfig.tsbuildinfo +0 -1
  128. package/dist/transports/http3-quiche/lib/clientsocket.d.ts +0 -19
  129. package/dist/transports/http3-quiche/lib/clientsocket.d.ts.map +0 -1
  130. package/dist/transports/http3-quiche/lib/index.d.ts +0 -11
  131. package/dist/transports/http3-quiche/lib/index.d.ts.map +0 -1
  132. package/dist/transports/http3-quiche/lib/serversocket.d.ts +0 -12
  133. package/dist/transports/http3-quiche/lib/serversocket.d.ts.map +0 -1
  134. package/dist/transports/http3-quiche/lib/socket.d.ts +0 -19
  135. package/dist/transports/http3-quiche/lib/socket.d.ts.map +0 -1
  136. package/dist/transports/http3-quiche/lib/types.d.ts +0 -21
  137. package/dist/transports/http3-quiche/lib/types.d.ts.map +0 -1
  138. package/dist/transports/http3-quiche/lib/utils.d.ts +0 -6
  139. package/dist/transports/http3-quiche/lib/utils.d.ts.map +0 -1
  140. /package/dist/{main/lib → lib}/client.d.ts +0 -0
  141. /package/dist/{main/lib → lib}/error.d.ts +0 -0
  142. /package/dist/{main/lib → lib}/features.d.ts +0 -0
  143. /package/dist/{main/lib → lib}/http2/browser/browserparser.d.ts +0 -0
  144. /package/dist/{main/lib → lib}/http2/node/index.d.ts +0 -0
  145. /package/dist/{main/lib → lib}/http2/parserbasehttp2.d.ts +0 -0
  146. /package/dist/{main/lib → lib}/http2/websocketcommon.d.ts +0 -0
  147. /package/dist/{main/lib → lib}/index.browser.d.ts +0 -0
  148. /package/dist/{main/lib → lib}/index.node.d.ts +0 -0
  149. /package/dist/{main/lib → lib}/server.d.ts +0 -0
  150. /package/dist/{main/lib → lib}/stream.d.ts +0 -0
  151. /package/dist/{main/lib → lib}/utils.d.ts +0 -0
  152. /package/dist/{main/lib → lib}/webstreams.browser.d.ts +0 -0
  153. /package/dist/{main/lib → lib}/webstreams.d.ts +0 -0
  154. /package/dist/{main/lib → lib}/webtransport.node.d.ts +0 -0
@@ -28,6 +28,10 @@ export class Http2WebTransportServer {
28
28
  this.initialSessionFlowControlWindow =
29
29
  args?.initialSessionFlowControlWindow || 16 * 1024 // 16 KB
30
30
 
31
+ this.initialBidirectionalStreams = args?.initialBidirectionalStreams || 100
32
+ this.initialUnidirectionalStreams =
33
+ args?.initialUnidirectionalStreams || 100
34
+
31
35
  this.streamShouldAutoTuneReceiveWindow =
32
36
  args.streamShouldAutoTuneReceiveWindow || false
33
37
  this.streamFlowControlWindowSizeLimit =
@@ -45,6 +49,8 @@ export class Http2WebTransportServer {
45
49
  // @ts-ignore
46
50
  this.jsobj = undefined // the transport will set this
47
51
 
52
+ this.canHandleSettings = false // TODO replace with version check, or other check once my patch lands in node
53
+
48
54
  // @ts-ignore
49
55
  this.serverInt = createSecureServer({
50
56
  key,
@@ -57,8 +63,8 @@ export class Http2WebTransportServer {
57
63
  0x2b61: this.initialSessionFlowControlWindow, // SETTINGS_WEBTRANSPORT_INITIAL_MAX_DATA
58
64
  0x2b62: this.initialStreamFlowControlWindow, // SETTINGS_WEBTRANSPORT_INITIAL_MAX_STREAM_DATA_UNI
59
65
  0x2b63: this.initialStreamFlowControlWindow, // SETTINGS_WEBTRANSPORT_INITIAL_MAX_STREAM_DATA_BIDI
60
- 0x2b64: 0xffffff, // SETTINGS_WEBTRANSPORT_INITIAL_MAX_STREAMS_UNI
61
- 0x2b65: 0xffffff // SETTINGS_WEBTRANSPORT_INITIAL_MAX_STREAMS_BIDI
66
+ 0x2b64: this.initialUnidirectionalStreams, // SETTINGS_WEBTRANSPORT_INITIAL_MAX_STREAMS_UNI
67
+ 0x2b65: this.initialBidirectionalStreams // SETTINGS_WEBTRANSPORT_INITIAL_MAX_STREAMS_BIDI
62
68
  }
63
69
  }
64
70
  })
@@ -147,8 +153,7 @@ export class Http2WebTransportServer {
147
153
  stream,
148
154
  nativesession,
149
155
  isclient: false,
150
- initialStreamSendWindowOffset:
151
- this.initialStreamFlowControlWindow,
156
+ initialStreamSendWindowOffset: 0,
152
157
  initialStreamReceiveWindowOffset:
153
158
  this.initialStreamFlowControlWindow,
154
159
  streamShouldAutoTuneReceiveWindow:
@@ -159,7 +164,13 @@ export class Http2WebTransportServer {
159
164
  if (head.byteLength > 0) parse.parseData(head)
160
165
  return parse
161
166
  },
162
- sendWindowOffset: this.sessionFlowControlWindowSizeLimit,
167
+ initialBidirectionalSendStreams: 0,
168
+ initialBidirectionalReceiveStreams:
169
+ this.initialBidirectionalStreams,
170
+ initialUnidirectionalSendStreams: 0,
171
+ initialUnidirectionalReceiveStreams:
172
+ this.initialUnidirectionalStreams,
173
+ sendWindowOffset: 0,
163
174
  receiveWindowOffset: this.sessionFlowControlWindowSizeLimit,
164
175
  shouldAutoTuneReceiveWindow:
165
176
  this.sessionShouldAutoTuneReceiveWindow,
@@ -246,7 +257,7 @@ export class Http2WebTransportServer {
246
257
  nativesession,
247
258
  isclient: false,
248
259
  initialStreamSendWindowOffset:
249
- this.initialStreamFlowControlWindow,
260
+ this.initialStreamFlowControlWindow, // TODO, once supported by node, use initial settings
250
261
  initialStreamReceiveWindowOffset:
251
262
  this.initialStreamFlowControlWindow,
252
263
  streamShouldAutoTuneReceiveWindow:
@@ -259,8 +270,7 @@ export class Http2WebTransportServer {
259
270
  stream,
260
271
  nativesession,
261
272
  isclient: false,
262
- initialStreamSendWindowOffset:
263
- this.initialStreamFlowControlWindow,
273
+ initialStreamSendWindowOffset: 0,
264
274
  initialStreamReceiveWindowOffset:
265
275
  this.initialStreamFlowControlWindow,
266
276
  streamShouldAutoTuneReceiveWindow:
@@ -270,7 +280,19 @@ export class Http2WebTransportServer {
270
280
  }))
271
281
  }
272
282
  },
273
- sendWindowOffset: this.sessionFlowControlWindowSizeLimit,
283
+ initialBidirectionalSendStreams: websocketProt // TODO, once supported by node, use initial settings
284
+ ? 0
285
+ : this.initialBidirectionalStreams,
286
+ initialBidirectionalReceiveStreams:
287
+ this.initialBidirectionalStreams,
288
+ initialUnidirectionalSendStreams: websocketProt
289
+ ? 0
290
+ : this.initialUnidirectionalStreams, // TODO, once supported by node, use initial settings
291
+ initialUnidirectionalReceiveStreams:
292
+ this.initialUnidirectionalStreams,
293
+ sendWindowOffset: !websocketProt
294
+ ? this.sessionFlowControlWindowSizeLimit
295
+ : 0, // TODO, once supported by node, use initial settings
274
296
  receiveWindowOffset: this.sessionFlowControlWindowSizeLimit,
275
297
  shouldAutoTuneReceiveWindow:
276
298
  this.sessionShouldAutoTuneReceiveWindow,
@@ -421,8 +443,7 @@ export class Http2WebTransportServer {
421
443
  stream,
422
444
  nativesession,
423
445
  isclient: false,
424
- initialStreamSendWindowOffset:
425
- this.initialStreamFlowControlWindow,
446
+ initialStreamSendWindowOffset: 0,
426
447
  initialStreamReceiveWindowOffset:
427
448
  this.initialStreamFlowControlWindow,
428
449
  streamShouldAutoTuneReceiveWindow:
@@ -433,7 +454,13 @@ export class Http2WebTransportServer {
433
454
  if (head && head.byteLength > 0) parse.parseData(head)
434
455
  return parse
435
456
  },
436
- sendWindowOffset: this.sessionFlowControlWindowSizeLimit,
457
+ initialBidirectionalSendStreams: 0,
458
+ initialBidirectionalReceiveStreams:
459
+ this.initialBidirectionalStreams,
460
+ initialUnidirectionalSendStreams: 0,
461
+ initialUnidirectionalReceiveStreams:
462
+ this.initialUnidirectionalStreams,
463
+ sendWindowOffset: 0,
437
464
  receiveWindowOffset: this.sessionFlowControlWindowSizeLimit,
438
465
  shouldAutoTuneReceiveWindow:
439
466
  this.sessionShouldAutoTuneReceiveWindow,
@@ -462,7 +489,7 @@ export class Http2WebTransportServer {
462
489
  nativesession,
463
490
  isclient: false,
464
491
  initialStreamSendWindowOffset:
465
- this.initialStreamFlowControlWindow,
492
+ this.initialStreamFlowControlWindow, // TODO, once supported by node, use initial settings
466
493
  initialStreamReceiveWindowOffset:
467
494
  this.initialStreamFlowControlWindow,
468
495
  streamShouldAutoTuneReceiveWindow:
@@ -475,8 +502,7 @@ export class Http2WebTransportServer {
475
502
  stream,
476
503
  nativesession,
477
504
  isclient: false,
478
- initialStreamSendWindowOffset:
479
- this.initialStreamFlowControlWindow,
505
+ initialStreamSendWindowOffset: 0,
480
506
  initialStreamReceiveWindowOffset:
481
507
  this.initialStreamFlowControlWindow,
482
508
  streamShouldAutoTuneReceiveWindow:
@@ -486,7 +512,18 @@ export class Http2WebTransportServer {
486
512
  }))
487
513
  }
488
514
  },
489
- sendWindowOffset: this.sessionFlowControlWindowSizeLimit,
515
+ initialBidirectionalSendStreams:
516
+ protocol !== 'websocket' ? this.initialBidirectionalStreams : 0, // TODO, once supported by node, use initial settings
517
+ initialBidirectionalReceiveStreams:
518
+ this.initialBidirectionalStreams,
519
+ initialUnidirectionalSendStreams:
520
+ protocol !== 'websocket' ? this.initialUnidirectionalStreams : 0, // TODO, once supported by node, use initial settings
521
+ initialUnidirectionalReceiveStreams:
522
+ this.initialUnidirectionalStreams,
523
+ sendWindowOffset:
524
+ protocol !== 'websocket'
525
+ ? this.sessionFlowControlWindowSizeLimit
526
+ : 0, // TODO, once supported by node, use initial settings
490
527
  receiveWindowOffset: this.sessionFlowControlWindowSizeLimit,
491
528
  shouldAutoTuneReceiveWindow:
492
529
  this.sessionShouldAutoTuneReceiveWindow,
@@ -193,6 +193,9 @@ export class WebSocketParser extends ParserBaseHttp2 {
193
193
  this.saveddata = undefined
194
194
  /** @type {Number|undefined} */
195
195
  this.rtype = undefined
196
+
197
+ this.bidirectionalLimitsSet = false
198
+ this.unidirectionalLimitsSet = false
196
199
  }
197
200
 
198
201
  /**
@@ -500,22 +503,30 @@ export class WebSocketParser extends ParserBaseHttp2 {
500
503
  case ParserBase.WT_STOP_SENDING:
501
504
  if (wbufferstate) {
502
505
  const streamid = readVarInt(wbufferstate)
503
- const stream = this.wtstreams.get(streamid)
504
- const code = readVarInt(wbufferstate)
505
- if (stream && typeof code !== 'undefined')
506
- stream.jsobj.onStreamRecvSignal({
507
- code,
508
- nettask:
506
+ if (typeof streamid !== 'undefined') {
507
+ const stream = this.wtstreams.get(streamid)
508
+ const code = readVarInt(wbufferstate)
509
+ if (stream && typeof code !== 'undefined') {
510
+ stream.onStreamSignal(
509
511
  type === ParserBase.WT_RESET_STREAM
510
512
  ? 'resetStream'
511
513
  : 'stopSending'
512
- })
514
+ )
515
+ stream.jsobj.onStreamRecvSignal({
516
+ code: Number(code),
517
+ nettask:
518
+ type === ParserBase.WT_RESET_STREAM
519
+ ? 'resetStream'
520
+ : 'stopSending'
521
+ })
522
+ }
523
+ }
513
524
  }
514
525
  break
515
526
  case ParserBase.WT_STREAM_WOFIN:
516
527
  case ParserBase.WT_STREAM_WFIN:
517
528
  if (!continuep) {
518
- streamid = Number(readVarInt(bufferstate))
529
+ streamid = readVarInt(bufferstate)
519
530
  this.cstreamid = streamid
520
531
  } else {
521
532
  streamid = this.cstreamid
@@ -524,9 +535,14 @@ export class WebSocketParser extends ParserBaseHttp2 {
524
535
  let object = this.wtstreams.get(streamid)
525
536
  if (!object) {
526
537
  object = this.newStream(streamid)
538
+ if (!object) return // stream broken
527
539
  }
528
540
  // TODO submit data
529
541
  if (offsetend - bufferstate.offset >= 0) {
542
+ const fin =
543
+ type === ParserBase.WT_STREAM_WFIN &&
544
+ bufferstate.size >= length + offsetbegin
545
+ if (fin) object.onFin()
530
546
  object.recvData({
531
547
  data:
532
548
  offsetend - bufferstate.offset > 0
@@ -537,9 +553,7 @@ export class WebSocketParser extends ParserBaseHttp2 {
537
553
  offsetend - bufferstate.offset
538
554
  )
539
555
  : undefined,
540
- fin:
541
- type === ParserBase.WT_STREAM_WFIN &&
542
- bufferstate.size >= length + offsetbegin
556
+ fin
543
557
  })
544
558
  }
545
559
  }
@@ -548,49 +562,41 @@ export class WebSocketParser extends ParserBaseHttp2 {
548
562
  this.onMaxData(readVarInt(bufferstate))
549
563
  break
550
564
  case ParserBase.WT_MAX_STREAM_DATA:
551
- this.onMaxStreamData(
552
- readVarInt(bufferstate),
553
- readVarInt(bufferstate)
554
- )
565
+ {
566
+ const streamid = readVarInt(bufferstate)
567
+ const offset = readVarInt(bufferstate)
568
+ if (
569
+ typeof streamid !== 'undefined' &&
570
+ typeof offset !== 'undefined'
571
+ )
572
+ this.onMaxStreamData(streamid, offset)
573
+ }
555
574
  break
556
575
  case ParserBase.WT_MAX_STREAMS_BIDI:
557
- // this.recvSession({ maxstreams: readVarInt(bufferstate), type })
576
+ this.onMaxStreamBiDi(readVarInt(bufferstate))
558
577
  break
559
578
  case ParserBase.WT_MAX_STREAMS_UNIDI:
560
- // this.recvSession({ maxstreams: readVarInt(bufferstate), type })
579
+ this.onMaxStreamUniDi(readVarInt(bufferstate))
561
580
  break
562
581
  case ParserBase.WT_DATA_BLOCKED:
563
582
  this.onDataBlocked(readVarInt(bufferstate))
564
583
  break
565
584
  case ParserBase.WT_STREAM_DATA_BLOCKED:
566
- this.onStreamDataBlocked(
567
- readVarInt(bufferstate),
568
- readVarInt(bufferstate)
569
- )
585
+ {
586
+ const streamid = readVarInt(bufferstate)
587
+ const offset = readVarInt(bufferstate)
588
+ if (
589
+ typeof streamid !== 'undefined' &&
590
+ typeof offset !== 'undefined'
591
+ )
592
+ this.onStreamDataBlocked(streamid, offset)
593
+ }
570
594
  break
571
595
  case ParserBase.WT_STREAMS_BLOCKED_UNIDI:
572
- /* {
573
- const streamid = readVarInt(bufferstate)
574
- const object = this.wtstreams.get(streamid)
575
- if (object)
576
- this.recvStream({
577
- maxstreams: readVarInt(bufferstate),
578
- type,
579
- object
580
- })
581
- } */
596
+ this.onStreamsBlockedUnidi(readVarInt(bufferstate))
582
597
  break
583
598
  case ParserBase.WT_STREAMS_BLOCKED_BIDI:
584
- /* {
585
- const streamid = readVarInt(bufferstate)
586
- const object = this.wtstreams.get(streamid)
587
- if (object)
588
- this.recvStream({
589
- maxstreams: readVarInt(bufferstate),
590
- type,
591
- streamid
592
- })
593
- } */
599
+ this.onStreamsBlockedBidi(readVarInt(bufferstate))
594
600
  break
595
601
  case ParserBase.DATAGRAM:
596
602
  if (wbufferstate) {
@@ -640,24 +646,28 @@ export class WebSocketParser extends ParserBaseHttp2 {
640
646
  // not in j mode
641
647
  // TODO submitData
642
648
  const object = this.wtstreams.get(this.rstreamid)
643
- if (this.maskcontext)
644
- applyMask(
645
- this.maskcontext,
646
- bufferstate.buffer,
647
- bufferstate.buffer.byteOffset + bufferstate.offset,
648
- clength
649
- )
650
- // TODO submit data
651
- object.recvData({
652
- data: new Uint8Array(
653
- bufferstate.buffer.buffer,
654
- bufferstate.buffer.byteOffset + bufferstate.offset,
655
- clength
656
- ),
657
- fin:
658
- this.rtype === ParserBase.WT_STREAM_WFIN &&
659
- this.remainlength === clength
660
- })
649
+ const fin =
650
+ this.rtype === ParserBase.WT_STREAM_WFIN &&
651
+ this.remainlength === clength
652
+ if (object) {
653
+ if (fin) object.onFin()
654
+ if (this.maskcontext)
655
+ applyMask(
656
+ this.maskcontext,
657
+ bufferstate.buffer,
658
+ bufferstate.buffer.byteOffset + bufferstate.offset,
659
+ clength
660
+ )
661
+ // TODO submit data
662
+ object.recvData({
663
+ data: new Uint8Array(
664
+ bufferstate.buffer.buffer,
665
+ bufferstate.buffer.byteOffset + bufferstate.offset,
666
+ clength
667
+ ),
668
+ fin
669
+ })
670
+ }
661
671
  }
662
672
 
663
673
  this.remainlength = this.remainlength - clength
@@ -1,4 +1,8 @@
1
1
  import { Http2WebTransportStream } from './stream.js'
2
+ import { logger } from '../utils.js'
3
+
4
+ const pid = typeof process !== 'undefined' ? process.pid : 0
5
+ const log = logger(`webtransport:parserbase(${pid})`)
2
6
 
3
7
  /**
4
8
  * @param{Number|bigint} int
@@ -49,6 +53,7 @@ export class ParserBase {
49
53
  this.streamShouldAutoTuneReceiveWindow = streamShouldAutoTuneReceiveWindow
50
54
  this.streamReceiveWindowSizeLimit = streamReceiveWindowSizeLimit
51
55
 
56
+ /** @type {Map<bigint,Http2WebTransportStream>} */
52
57
  this.wtstreams = new Map()
53
58
  }
54
59
 
@@ -74,22 +79,44 @@ export class ParserBase {
74
79
  sendClose({ code, reason }) {}
75
80
 
76
81
  /**
77
- * @param {Number} streamid
82
+ * @param {bigint} streamid
78
83
  */
79
84
  newStream(streamid) {
85
+ const incoming = this.isclient ? !(streamid & 0x1n) : !!(streamid & 0x1n)
86
+ const streamIdManager =
87
+ streamid & 0x2n
88
+ ? this.session.streamIdMngrUni
89
+ : this.session.streamIdMngrBi
90
+
91
+ if (incoming) {
92
+ // only check incoming streams
93
+ const res = streamIdManager.maybeIncreaseLargestPeerStreamId(streamid)
94
+ if (res.error) {
95
+ // ok someone overstayed its welcome
96
+ this.session.closeConnection({
97
+ code: 20, // QUIC_STREAM_STREAM_CREATION_ERROR , // probably the right one...
98
+ reason: res.error
99
+ })
100
+
101
+ return undefined
102
+ }
103
+ }
80
104
  const stream = new Http2WebTransportStream({
81
105
  streamid,
106
+ unidirectional: !!(streamid & 0x2n),
107
+ incoming,
82
108
  capsuleParser: this,
83
109
  sendWindowOffset: this.initialStreamSendWindowOffset,
84
110
  receiveWindowOffset: this.initialStreamReceiveWindowOffset,
85
111
  shouldAutoTuneReceiveWindow: this.streamShouldAutoTuneReceiveWindow,
86
112
  receiveWindowSizeLimit: this.streamReceiveWindowSizeLimit,
87
- sessionFlowController: this.session.flowController
113
+ sessionFlowController: this.session.flowController,
114
+ streamIdManager
88
115
  })
89
116
  this.wtstreams.set(streamid, stream)
90
117
  this.session.jsobj.onStream({
91
- bidirectional: !(streamid & 0x2),
92
- incoming: this.isclient ? !(streamid & 0x1) : !!(streamid & 0x1),
118
+ bidirectional: !(streamid & 0x2n),
119
+ incoming,
93
120
  stream
94
121
  })
95
122
  return stream
@@ -110,31 +137,79 @@ export class ParserBase {
110
137
  }
111
138
 
112
139
  /**
113
- * @param {bigint|undefined} streamid
114
- * @param {bigint|undefined} offset
140
+ * @param {bigint} streamid
141
+ * @param {bigint} offset
115
142
  */
116
143
  onMaxStreamData(streamid, offset) {
117
- const object = this.wtstreams.get(Number(streamid))
144
+ const object = this.wtstreams.get(streamid)
118
145
  if (object && offset) {
119
146
  if (object.flowController.updateSendWindowOffset(offset))
120
147
  object.drainWrites()
121
148
  }
122
149
  }
123
150
 
151
+ /**
152
+ * @param {bigint|undefined} maxOpenStreams
153
+ */
154
+ onMaxStreamUniDi(maxOpenStreams) {
155
+ if (typeof maxOpenStreams === 'undefined') return
156
+ this.session.streamIdMngrUni.maybeAllowNewOutgoingStreams(maxOpenStreams)
157
+ this.session.trySendingUnidirectionalStreams()
158
+ }
159
+
160
+ /**
161
+ * @param {bigint|undefined} maxOpenStreams
162
+ */
163
+ onMaxStreamBiDi(maxOpenStreams) {
164
+ if (typeof maxOpenStreams === 'undefined') return
165
+ this.session.streamIdMngrBi.maybeAllowNewOutgoingStreams(maxOpenStreams)
166
+ this.session.trySendingBidirectionalStreams()
167
+ }
168
+
124
169
  /**
125
170
  * @param {bigint|undefined} val
126
171
  */
127
172
  onDataBlocked(val) {
128
- this.session.flowController.reportBlocked(val)
173
+ log('Session received blocked frame ' + val)
174
+ // this.session.flowController.reportBlocked(val)
129
175
  }
130
176
 
131
177
  /**
132
- * @param {bigint|undefined} streamid
133
- * @param {bigint|undefined} offset
178
+ * @param {bigint} streamid
179
+ * @param {bigint} offset
134
180
  */
135
181
  onStreamDataBlocked(streamid, offset) {
136
- const object = this.wtstreams.get(Number(streamid))
137
- if (object && offset) object.flowController.reportBlocked(offset)
182
+ log('Stream ' + streamid + ' received blocked frame ' + offset)
183
+ // const object = this.wtstreams.get(streamid)
184
+ // if (object && offset) object.flowController.reportBlocked(offset)
185
+ }
186
+
187
+ /**
188
+ * @param {bigint|undefined} maxstreams
189
+ */
190
+ onStreamsBlockedBidi(maxstreams) {
191
+ if (typeof maxstreams === 'undefined') return
192
+ const ret = this.session.streamIdMngrBi.onStreamsBlockedFrame(maxstreams)
193
+ if (ret.error) {
194
+ this.session.closeConnection({
195
+ code: 105, // QUIC_STREAMS_BLOCKED_DATA , // probably the right one...
196
+ reason: ret.error
197
+ })
198
+ }
199
+ }
200
+
201
+ /**
202
+ * @param {bigint|undefined} maxstreams
203
+ */
204
+ onStreamsBlockedUnidi(maxstreams) {
205
+ if (typeof maxstreams === 'undefined') return
206
+ const ret = this.session.streamIdMngrUni.onStreamsBlockedFrame(maxstreams)
207
+ if (ret.error) {
208
+ this.session.closeConnection({
209
+ code: 105, // QUIC_STREAMS_BLOCKED_DATA , // probably the right one...
210
+ reason: ret.error
211
+ })
212
+ }
138
213
  }
139
214
 
140
215
  /**