@fails-components/webtransport 0.3.1 → 1.0.1

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 (162) hide show
  1. package/lib/client.js +81 -40
  2. package/lib/dom.ts +7 -5
  3. package/lib/http2/browser/browser.js +168 -0
  4. package/lib/http2/browser/browserparser.js +248 -0
  5. package/lib/http2/flowcontroller.js +371 -0
  6. package/lib/http2/node/capsuleparser.js +291 -0
  7. package/lib/http2/node/client.js +239 -0
  8. package/lib/http2/node/index.js +2 -0
  9. package/lib/http2/node/server.js +499 -0
  10. package/lib/http2/node/websocketparser.js +829 -0
  11. package/lib/http2/parserbase.js +139 -0
  12. package/lib/http2/parserbasehttp2.js +128 -0
  13. package/lib/http2/session.js +225 -0
  14. package/lib/http2/stream.js +354 -0
  15. package/lib/http2/websocketcommon.js +1 -0
  16. package/lib/{index.js → index.browser.js} +6 -10
  17. package/lib/index.node.js +27 -0
  18. package/lib/server.js +252 -69
  19. package/lib/session.js +31 -68
  20. package/lib/stream.js +103 -179
  21. package/lib/types.ts +174 -87
  22. package/lib/utils.js +2 -1
  23. package/lib/webstreams.browser.js +6 -0
  24. package/lib/webstreams.js +7 -0
  25. package/lib/webtransport.browser.js +284 -0
  26. package/lib/webtransport.node.js +137 -0
  27. package/lib/{webtransport.js → webtransportbase.js} +47 -41
  28. package/old_test/test.js +31 -29
  29. package/old_test/testsuite.js +1 -1
  30. package/package.json +18 -17
  31. package/readme.md +94 -30
  32. package/test/bidirectional-streams.spec.js +51 -9
  33. package/test/datagrams.spec.js +8 -2
  34. package/test/fixtures/known-bytes.js +29 -0
  35. package/test/fixtures/read-stream.js +1 -1
  36. package/test/fixtures/reader-value.js +1 -1
  37. package/test/fixtures/server.js +24 -10
  38. package/test/fixtures/webtransport.browser.js +20 -2
  39. package/test/fixtures/webtransport.js +1 -1
  40. package/test/index.js +33 -6
  41. package/test/pw-no-https-errors.json +5 -0
  42. package/test/session.spec.js +71 -52
  43. package/test/unidirectional-streams.spec.js +20 -4
  44. package/CMakeLists.txt +0 -991
  45. package/LICENSE.chromium +0 -27
  46. package/LICENSE.envoy +0 -207
  47. package/build.js +0 -313
  48. package/dist/lib/client.d.ts +0 -78
  49. package/dist/lib/client.d.ts.map +0 -1
  50. package/dist/lib/dom.d.ts +0 -87
  51. package/dist/lib/dom.d.ts.map +0 -1
  52. package/dist/lib/error.d.ts +0 -8
  53. package/dist/lib/error.d.ts.map +0 -1
  54. package/dist/lib/event-loop.d.ts +0 -33
  55. package/dist/lib/event-loop.d.ts.map +0 -1
  56. package/dist/lib/index.d.ts +0 -79
  57. package/dist/lib/index.d.ts.map +0 -1
  58. package/dist/lib/native.d.ts +0 -2
  59. package/dist/lib/native.d.ts.map +0 -1
  60. package/dist/lib/server.d.ts +0 -92
  61. package/dist/lib/server.d.ts.map +0 -1
  62. package/dist/lib/session.d.ts +0 -298
  63. package/dist/lib/session.d.ts.map +0 -1
  64. package/dist/lib/stream.d.ts +0 -135
  65. package/dist/lib/stream.d.ts.map +0 -1
  66. package/dist/lib/transport.d.ts +0 -34
  67. package/dist/lib/transport.d.ts.map +0 -1
  68. package/dist/lib/types.d.ts +0 -212
  69. package/dist/lib/types.d.ts.map +0 -1
  70. package/dist/lib/utils.d.ts +0 -11
  71. package/dist/lib/utils.d.ts.map +0 -1
  72. package/dist/lib/webtransport.d.ts +0 -47
  73. package/dist/lib/webtransport.d.ts.map +0 -1
  74. package/dist/test/bidirectional-streams.spec.d.ts +0 -5
  75. package/dist/test/bidirectional-streams.spec.d.ts.map +0 -1
  76. package/dist/test/datagrams.spec.d.ts +0 -5
  77. package/dist/test/datagrams.spec.d.ts.map +0 -1
  78. package/dist/test/event-loop.node.d.ts +0 -2
  79. package/dist/test/event-loop.node.d.ts.map +0 -1
  80. package/dist/test/fixtures/certificate.d.ts +0 -21
  81. package/dist/test/fixtures/certificate.d.ts.map +0 -1
  82. package/dist/test/fixtures/chai.d.ts +0 -2
  83. package/dist/test/fixtures/chai.d.ts.map +0 -1
  84. package/dist/test/fixtures/known-bytes.d.ts +0 -6
  85. package/dist/test/fixtures/known-bytes.d.ts.map +0 -1
  86. package/dist/test/fixtures/p-timeout.d.ts +0 -8
  87. package/dist/test/fixtures/p-timeout.d.ts.map +0 -1
  88. package/dist/test/fixtures/read-cert-hash.d.ts +0 -6
  89. package/dist/test/fixtures/read-cert-hash.d.ts.map +0 -1
  90. package/dist/test/fixtures/read-stream.d.ts +0 -19
  91. package/dist/test/fixtures/read-stream.d.ts.map +0 -1
  92. package/dist/test/fixtures/reader-value.d.ts +0 -22
  93. package/dist/test/fixtures/reader-value.d.ts.map +0 -1
  94. package/dist/test/fixtures/server.d.ts +0 -5
  95. package/dist/test/fixtures/server.d.ts.map +0 -1
  96. package/dist/test/fixtures/webtransport.browser.d.ts +0 -3
  97. package/dist/test/fixtures/webtransport.browser.d.ts.map +0 -1
  98. package/dist/test/fixtures/webtransport.d.ts +0 -3
  99. package/dist/test/fixtures/webtransport.d.ts.map +0 -1
  100. package/dist/test/fixtures/write-stream.d.ts +0 -10
  101. package/dist/test/fixtures/write-stream.d.ts.map +0 -1
  102. package/dist/test/index.d.ts +0 -2
  103. package/dist/test/index.d.ts.map +0 -1
  104. package/dist/test/session.spec.d.ts +0 -5
  105. package/dist/test/session.spec.d.ts.map +0 -1
  106. package/dist/test/unidirectional-streams.spec.d.ts +0 -2
  107. package/dist/test/unidirectional-streams.spec.d.ts.map +0 -1
  108. package/failslogolicensereadme.txt +0 -4
  109. package/lib/event-loop.js +0 -88
  110. package/lib/native.js +0 -28
  111. package/lib/transport.js +0 -82
  112. package/platform/icufix/fakedata.cpp +0 -8
  113. package/platform/quiche/quic/core/io/socket_win.inc +0 -3
  114. package/platform/quiche_platform_impl/quiche_bug_tracker_impl.h +0 -7
  115. package/platform/quiche_platform_impl/quiche_client_stats_impl.h +0 -7
  116. package/platform/quiche_platform_impl/quiche_command_line_flags_impl.h +0 -7
  117. package/platform/quiche_platform_impl/quiche_containers_impl.h +0 -7
  118. package/platform/quiche_platform_impl/quiche_event_loop_impl.h +0 -7
  119. package/platform/quiche_platform_impl/quiche_export_impl.h +0 -6
  120. package/platform/quiche_platform_impl/quiche_flag_utils_impl.h +0 -11
  121. package/platform/quiche_platform_impl/quiche_flags_impl.h +0 -8
  122. package/platform/quiche_platform_impl/quiche_iovec_impl.h +0 -10
  123. package/platform/quiche_platform_impl/quiche_logging_impl.h +0 -21
  124. package/platform/quiche_platform_impl/quiche_mem_slice_impl.h +0 -2
  125. package/platform/quiche_platform_impl/quiche_mutex_impl.h +0 -8
  126. package/platform/quiche_platform_impl/quiche_prefetch_impl.h +0 -11
  127. package/platform/quiche_platform_impl/quiche_reference_counted_impl.h +0 -16
  128. package/platform/quiche_platform_impl/quiche_server_stats_impl.h +0 -7
  129. package/platform/quiche_platform_impl/quiche_stack_trace_impl.h +0 -12
  130. package/platform/quiche_platform_impl/quiche_stream_buffer_allocator_impl.h +0 -8
  131. package/platform/quiche_platform_impl/quiche_testvalue_impl.h +0 -1
  132. package/platform/quiche_platform_impl/quiche_thread_local_impl.h +0 -6
  133. package/platform/quiche_platform_impl/quiche_time_utils_impl.h +0 -13
  134. package/platform/quiche_platform_impl/quiche_udp_socket_platform_impl.h +0 -39
  135. package/src/http3backendresponse.cc +0 -36
  136. package/src/http3backendresponse.h +0 -109
  137. package/src/http3client.cc +0 -1529
  138. package/src/http3client.h +0 -557
  139. package/src/http3clientsession.cc +0 -65
  140. package/src/http3clientsession.h +0 -60
  141. package/src/http3clientstream.cc +0 -52
  142. package/src/http3clientstream.h +0 -42
  143. package/src/http3dispatcher.cc +0 -62
  144. package/src/http3dispatcher.h +0 -57
  145. package/src/http3eventloop.cc +0 -1107
  146. package/src/http3eventloop.h +0 -316
  147. package/src/http3server.cc +0 -514
  148. package/src/http3server.h +0 -151
  149. package/src/http3serverbackend.cc +0 -105
  150. package/src/http3serverbackend.h +0 -98
  151. package/src/http3serversession.cc +0 -123
  152. package/src/http3serversession.h +0 -95
  153. package/src/http3serverstream.cc +0 -463
  154. package/src/http3serverstream.h +0 -114
  155. package/src/http3sessioncache.cc +0 -85
  156. package/src/http3sessioncache.h +0 -59
  157. package/src/http3wtsessionvisitor.cc +0 -46
  158. package/src/http3wtsessionvisitor.h +0 -397
  159. package/src/http3wtstreamvisitor.cc +0 -155
  160. package/src/http3wtstreamvisitor.h +0 -404
  161. package/test/event-loop.node.js +0 -24
  162. package/tsconfig.json +0 -39
@@ -0,0 +1,284 @@
1
+ import { WebTransportBase } from './webtransportbase.js'
2
+ import { HttpWTSession } from './session.js'
3
+ import { HttpClient } from './client.js'
4
+ import { Http2WebTransportBrowser } from './http2/browser/browser.js'
5
+
6
+ /**
7
+ * @typedef {import('./dom').WebTransport} WebTransport
8
+ * @typedef {import('./dom').WebTransportCloseInfo} WebTransportCloseInfo
9
+ * @typedef {import('./dom').WebTransportBidirectionalStream} WebTransportBidirectionalStream
10
+ * @typedef {import('./dom').WebTransportReceiveStream} WebTransportReceiveStream
11
+ * @typedef {import('./error').WebTransportError} WebTransportError
12
+ */
13
+
14
+ /**
15
+ * @template T
16
+ * @typedef {import('node:stream/web').ReadableStream<T>} ReadableStream<T>
17
+ */
18
+
19
+ /**
20
+ * @typedef {import('./dom').WebTransport} WebTransportInterface
21
+ *
22
+ * @implements {WebTransportInterface}
23
+ */
24
+ export class WebTransportPonyfill extends WebTransportBase {
25
+ /**
26
+ * @param{{client: HttpClient, sessionint: HttpWTSession, ourl: URL}} args
27
+ */
28
+ startUpConnection({ client, sessionint, ourl }) {
29
+ client
30
+ .handleConnection({ createTransport: true, path: ourl.pathname })
31
+ .then(() => client.createWTSession(sessionint, ourl.pathname))
32
+ .catch((error) => {
33
+ client.closeHookSession()
34
+ sessionint.readyReject(error)
35
+ sessionint.closedReject(error)
36
+ })
37
+ }
38
+
39
+ get supportsReliableOnly() {
40
+ return true
41
+ }
42
+
43
+ /**
44
+ * @param{import('./types.js').HttpWebTransportInit} args
45
+ * @return {{sessionint: HttpWTSession, client: HttpClient}}
46
+ */
47
+ createClient(args) {
48
+ this.curtype = 'websocket'
49
+ const client = new HttpClient({
50
+ createReliableClient: (client) => {
51
+ // @ts-ignore
52
+ return new Http2WebTransportBrowser({ ...args })
53
+ },
54
+ ...args
55
+ })
56
+ const sessionint = new HttpWTSession({
57
+ /* object: args.session, */
58
+ parentobj: client
59
+ })
60
+ return { client, sessionint }
61
+ }
62
+ }
63
+
64
+ export class WebTransportPolyfill {
65
+ /**
66
+ * @param {string} url
67
+ * @param {import('./dom.js').WebTransportOptions} [args]
68
+ */
69
+ constructor(url, args) {
70
+ this.curtype = 'native'
71
+ this.closeset = false
72
+ this.allowFallback = true
73
+ this.initiatedFallback = false
74
+ this.args = args
75
+
76
+ this.closed = new Promise((resolve, reject) => {
77
+ this.closeRes = resolve
78
+ this.closeRej = reject
79
+ })
80
+
81
+ this.ready = new Promise((resolve, reject) => {
82
+ this.readyRes = resolve
83
+ this.readyRej = reject
84
+ })
85
+
86
+ this.draining = new Promise((resolve, reject) => {
87
+ this.drainingRes = resolve
88
+ this.drainingRej = reject
89
+ })
90
+
91
+ const initiateFallback = () => {
92
+ this.initiatedFallback = true
93
+ this.curtype = 'websocket'
94
+ this.curtransport = new WebTransportPonyfill(url, args)
95
+ this.curtransport.ready
96
+ .then((val) => this.readyRes(val))
97
+ .catch((error) => this.readyRej(error))
98
+ this.curtransport.closed
99
+ .then((val) => this.closeRes(val))
100
+ .catch((error) => this.closeRej(error))
101
+ this.curtransport.draining
102
+ .then((val) => this.drainingRes(val))
103
+ .catch((error) => this.drainingRej(error))
104
+ }
105
+ // @ts-ignore
106
+ if (globalThis.WebTransport) {
107
+ /** @type {WebTransport|WebTransportPonyfill} */
108
+ // @ts-ignore
109
+ // eslint-disable-next-line no-undef
110
+ this.curtransport = new WebTransport(url, args)
111
+ // if browser takes too long for waiting for client, we use the ponyfill
112
+ setTimeout(() => {
113
+ if (this.allowFallback && !this.closeset) {
114
+ if (
115
+ !this.initiatedFallback &&
116
+ !this.curtransport?.supportsReliableOnly // way how browser signals support for http/2, no polyfill needed in this cases
117
+ ) {
118
+ const oldtransport = this.curtransport
119
+ if (oldtransport)
120
+ oldtransport.ready
121
+ .then(async () => {
122
+ oldtransport.close()
123
+ })
124
+ .catch(() => {})
125
+ initiateFallback()
126
+ }
127
+ }
128
+ }, 2000)
129
+
130
+ this.curtransport.ready
131
+ .then((val) => {
132
+ this.allowFallback = false
133
+ this.readyRes(val)
134
+ })
135
+ .catch((error) => {
136
+ if (this.allowFallback && !this.closeset) {
137
+ if (
138
+ !this.initiatedFallback &&
139
+ !this.curtransport?.supportsReliableOnly // way how browser signals support for http/2, no polyfill needed in this cases
140
+ ) {
141
+ initiateFallback()
142
+ }
143
+ } else {
144
+ this.readyRej(error)
145
+ }
146
+ })
147
+ this.curtransport.closed
148
+ .then((val) => {
149
+ if (this.curtype === 'native') this.closeRes(val)
150
+ })
151
+ .catch((error) => {
152
+ if (this.allowFallback && !this.closeset) {
153
+ if (
154
+ !this.initiatedFallback &&
155
+ !this.curtransport?.supportsReliableOnly // way how browser signals support for http/2, no polyfill needed in this cases
156
+ ) {
157
+ initiateFallback()
158
+ }
159
+ } else {
160
+ this.closeRej(error)
161
+ }
162
+ })
163
+ if (this.curtransport.draining) {
164
+ // @ts-ignore
165
+ this.curtransport.draining
166
+ .then((/** @type {any} */ val) => {
167
+ if (this.curtype === 'native') this.drainingRes(val)
168
+ })
169
+ .catch((/** @type {WebTransportError} */ error) => {
170
+ if (this.curtype === 'native') this.drainingRej(error)
171
+ })
172
+ }
173
+ } else {
174
+ initiateFallback()
175
+ }
176
+ /** @type {import('./dom').WebTransportDatagramDuplexStream} */
177
+ // @ts-ignore
178
+ this.datagrams = {}
179
+ // @ts-ignore
180
+ // eslint-disable-next-line no-undef
181
+ this.datagrams.readable = new ReadableStream({
182
+ start: async (controller) => {
183
+ await this.ready
184
+ this.datagramsReader = this.curtransport.datagrams.readable.getReader()
185
+ },
186
+ pull: async (controller) => {
187
+ const { value, done } = await this.datagramsReader.read()
188
+ if (value) controller.enqueue(value)
189
+ if (done) controller.close()
190
+ },
191
+ cancel: async (reason) => {
192
+ await this.datagramsReader.cancel(reason)
193
+ }
194
+ })
195
+ // @ts-ignore
196
+ // eslint-disable-next-line no-undef
197
+ this.datagrams.writable = new WritableStream({
198
+ start: async (controller) => {
199
+ await this.ready
200
+ this.datagramsWriter = this.curtransport.datagrams.writable.getWriter()
201
+ },
202
+ write: async (chunk, controller) => {
203
+ await this.datagramsWriter.write(chunk)
204
+ },
205
+ abort: async (reason) => {
206
+ await this.datagramsWriter.abort(reason)
207
+ },
208
+ close: async () => {
209
+ await this.datagramsWriter.close()
210
+ }
211
+ })
212
+ // eslint-disable-next-line no-undef
213
+ this.incomingBidirectionalStreams = new ReadableStream({
214
+ start: async (controller) => {
215
+ await this.ready
216
+ this.incomingBidirectionalStreamsReader =
217
+ this.curtransport.incomingBidirectionalStreams.getReader()
218
+ },
219
+ pull: async (controller) => {
220
+ const { value, done } =
221
+ await this.incomingBidirectionalStreamsReader.read()
222
+ if (value) controller.enqueue(value)
223
+ if (done) controller.close()
224
+ },
225
+ cancel: async (reason) => {
226
+ await this.incomingBidirectionalStreamsReader.cancel(reason)
227
+ }
228
+ })
229
+ // eslint-disable-next-line no-undef
230
+ this.incomingUnidirectionalStreams = new ReadableStream({
231
+ start: async (controller) => {
232
+ await this.ready
233
+ this.incomingUnidirectionalStreamsReader =
234
+ this.curtransport.incomingUnidirectionalStreams.getReader()
235
+ },
236
+ pull: async (controller) => {
237
+ const { value, done } =
238
+ await this.incomingUnidirectionalStreamsReader.read()
239
+ if (value) controller.enqueue(value)
240
+ if (done) controller.close()
241
+ },
242
+ cancel: async (reason) => {
243
+ await this.incomingUnidirectionalStreamsReader.cancel(reason)
244
+ }
245
+ })
246
+ }
247
+
248
+ get congestionControl() {
249
+ // @ts-ignore
250
+ return this.curtransport?.congestionControl || undefined
251
+ }
252
+
253
+ get reliability() {
254
+ // @ts-ignore
255
+ return this.curtransport?.reliability || undefined
256
+ }
257
+
258
+ get supportsReliableOnly() {
259
+ return true
260
+ }
261
+
262
+ getStats() {
263
+ // @ts-ignore
264
+ return this.curtransport.getStats()
265
+ }
266
+
267
+ /**
268
+ * @param {WebTransportCloseInfo} [closeinfo]
269
+ */
270
+ close(closeinfo) {
271
+ this.closeset = true
272
+ this.curtransport.close(closeinfo)
273
+ }
274
+
275
+ async createBidirectionalStream() {
276
+ await this.ready
277
+ return await this.curtransport.createBidirectionalStream()
278
+ }
279
+
280
+ async createUnidirectionalStream() {
281
+ await this.ready
282
+ return await this.curtransport.createUnidirectionalStream()
283
+ }
284
+ }
@@ -0,0 +1,137 @@
1
+ import { HttpWTSession } from './session.js'
2
+ import { WebTransportBase } from './webtransportbase.js'
3
+ import { HttpClient } from './client.js'
4
+ import { Http2WebTransportClient } from './http2/node/index.js'
5
+ import { logger } from './utils.js'
6
+
7
+ const log = logger(`webtransportnode(${process?.pid})`)
8
+
9
+ /**
10
+ * @type {(arg0: import("./types").HttpWebTransportInit) => void}
11
+ */
12
+ let checkQuicheInit
13
+ /**
14
+ * @type {new (arg0: import("./types").HttpWebTransportInit) => any}
15
+ */
16
+ let Http3WebTransportClientSocket
17
+ /**
18
+ * @type {new (arg0: import("./types").HttpWebTransportInit) => any}
19
+ */
20
+ let Http3WebTransportClient
21
+ // @ts-ignore
22
+ // eslint-disable-next-line no-unused-vars
23
+ const quicheLoaded = new Promise((resolve, reject) => {
24
+ // @ts-ignore
25
+ import('@fails-components/webtransport-transport-http3-quiche')
26
+ .then(
27
+ /**
28
+ * @type {import("./types").TransportHttp3Quiche}
29
+ */
30
+ (http3lib) => {
31
+ /**
32
+ * @type {import("./types").TransportHttp3Quiche}
33
+ */
34
+ ;({
35
+ checkQuicheInit,
36
+ Http3WebTransportClientSocket,
37
+ Http3WebTransportClient
38
+ } = http3lib)
39
+ resolve(undefined)
40
+ }
41
+ )
42
+ .catch((error) => {
43
+ log('Problem loading http3-quiche transport', error)
44
+ reject(error)
45
+ })
46
+ }).catch((error) => {
47
+ console.log('http3 loader:', error)
48
+ })
49
+
50
+ /**
51
+ * @typedef {import('./dom').WebTransportCloseInfo} WebTransportCloseInfo
52
+ * @typedef {import('./dom').WebTransportBidirectionalStream} WebTransportBidirectionalStream
53
+ * @typedef {import('./dom').WebTransportReceiveStream} WebTransportReceiveStream
54
+ */
55
+
56
+ /**
57
+ * @template T
58
+ * @typedef {import('node:stream/web').ReadableStream<T>} ReadableStream<T>
59
+ */
60
+
61
+ /**
62
+ * @typedef {import('./dom').WebTransport} WebTransportInterface
63
+ *
64
+ * @implements {WebTransportInterface}
65
+ */
66
+ export class WebTransport extends WebTransportBase {
67
+ /**
68
+ * @param{{client: HttpClient, sessionint: HttpWTSession, ourl: URL}} args
69
+ */
70
+ startUpConnection({ client, sessionint, ourl }) {
71
+ client
72
+ .handleConnection({ createTransport: true, path: ourl.pathname })
73
+ .then(() => client.createWTSession(sessionint, ourl.pathname))
74
+ .catch((error) => {
75
+ if (client.transportIntSwitchToReliable) {
76
+ log('Connecting to unreliable failed:', error)
77
+ log('Now switching to reliable')
78
+ client.transportIntSwitchToReliable()
79
+ client
80
+ .handleConnection({ createTransport: false, path: ourl.pathname })
81
+ .then(() => client.createWTSession(sessionint, ourl.pathname))
82
+ .catch((error) => {
83
+ client.closeHookSession()
84
+ sessionint.readyReject(error)
85
+ sessionint.closedReject(error)
86
+ })
87
+ } else {
88
+ client.closeHookSession()
89
+ sessionint.readyReject(error)
90
+ sessionint.closedReject(error)
91
+ }
92
+ })
93
+ }
94
+
95
+ get supportsReliableOnly() {
96
+ return true
97
+ }
98
+
99
+ /**
100
+ * @param{import('./types.js').HttpWebTransportInit} args
101
+ * @return {{sessionint: HttpWTSession, client: HttpClient}}
102
+ */
103
+ createClient(args) {
104
+ let createUnreliableClient
105
+ if (checkQuicheInit) {
106
+ createUnreliableClient = function (/** @type {any} */ _client) {
107
+ if (
108
+ // @ts-ignore
109
+ !args?.forceReliable
110
+ ) {
111
+ checkQuicheInit(args)
112
+ }
113
+ const socket = new Http3WebTransportClientSocket(args)
114
+ const uclient = new Http3WebTransportClient(args)
115
+ uclient.closeClientInt = uclient.closeClient
116
+ uclient.closeClient = socket.closeClient.bind(socket)
117
+ socket.init()
118
+ socket.cobj = uclient
119
+ uclient.socket = socket
120
+ return uclient
121
+ }
122
+ }
123
+ const client = new HttpClient({
124
+ createReliableClient: function (client) {
125
+ // @ts-ignore
126
+ return new Http2WebTransportClient({ ...args })
127
+ },
128
+ createUnreliableClient,
129
+ ...args
130
+ })
131
+ const sessionint = new HttpWTSession({
132
+ /* object: args.session, */
133
+ parentobj: client
134
+ })
135
+ return { client, sessionint }
136
+ }
137
+ }
@@ -1,13 +1,11 @@
1
- import { Http3Client } from './client.js'
2
- import { Http3WTSession } from './session.js'
3
-
4
- /** @type {WeakMap<WebTransport, Http3WTSession>} */
5
- const sessions = new WeakMap()
1
+ /** @type {WeakMap<WebTransportBase, import('./session.js').HttpWTSession>} */
6
2
 
7
3
  /**
8
- * @typedef {import('./dom').WebTransportCloseInfo} WebTransportCloseInfo
9
- * @typedef {import('./dom').WebTransportBidirectionalStream} WebTransportBidirectionalStream
10
- * @typedef {import('./dom').WebTransportReceiveStream} WebTransportReceiveStream
4
+ * @typedef {import('./dom.js').WebTransportCloseInfo} WebTransportCloseInfo
5
+ * @typedef {import('./dom.js').WebTransportBidirectionalStream} WebTransportBidirectionalStream
6
+ * @typedef {import('./dom.js').WebTransportReceiveStream} WebTransportReceiveStream
7
+ * @typedef {import('./session.js').HttpWTSession} HttpWTSession
8
+ * @typedef { import('./session.js').HttpClient} HttpClient
11
9
  */
12
10
 
13
11
  /**
@@ -16,14 +14,14 @@ const sessions = new WeakMap()
16
14
  */
17
15
 
18
16
  /**
19
- * @typedef {import('./dom').WebTransport} WebTransportInterface
17
+ * @typedef {import('./dom.js').WebTransport} WebTransportInterface
20
18
  *
21
19
  * @implements {WebTransportInterface}
22
20
  */
23
- export class WebTransport {
21
+ export class WebTransportBase {
24
22
  /**
25
23
  * @param {string} url
26
- * @param {import('./dom').WebTransportOptions} [args]
24
+ * @param {import('./dom.js').WebTransportOptions} [args]
27
25
  */
28
26
  constructor(url, args) {
29
27
  if (!url) throw new Error('no URL supplied')
@@ -37,42 +35,44 @@ export class WebTransport {
37
35
  const host = ourl.hostname
38
36
  let port = ourl.port
39
37
  if (port === '') port = '443'
40
-
41
- const client = new Http3Client({ host, port, ...args })
42
-
43
- const sessionint = new Http3WTSession({
44
- /* object: args.session, */
45
- parentobj: client
46
- })
47
-
38
+ const { sessionint, client } = this.createClient({ host, port, ...args })
48
39
  this.ready = sessionint.ready
49
40
  this.closed = sessionint.closed
50
41
  this.draining = sessionint.draining
51
42
 
52
43
  this.datagrams = sessionint.datagrams
53
44
 
54
- /** @type {ReadableStream<WebTransportBidirectionalStream>} */
55
45
  this.incomingBidirectionalStreams = sessionint.incomingBidirectionalStreams
56
46
 
57
47
  this.incomingUnidirectionalStreams =
58
48
  sessionint.incomingUnidirectionalStreams
59
49
 
60
- sessions.set(this, sessionint)
50
+ this.sessionint = sessionint
51
+
52
+ this.startUpConnection({ client, sessionint, ourl })
53
+ }
54
+
55
+ /**
56
+ * @param{import('./types.js').HttpWebTransportInit} args
57
+ * @return {{sessionint: HttpWTSession, client: HttpClient}}
58
+ * @abstract
59
+ */
60
+ createClient(args) {
61
+ throw new Error('Implement createClient')
62
+ }
61
63
 
62
- client
63
- .handleConnection()
64
- .then(() => client.createWTSession(sessionint, ourl.pathname))
65
- .catch((error) => {
66
- client.closeHookSession()
67
- sessionint.readyReject(error)
68
- sessionint.closedReject(error)
69
- })
64
+ /**
65
+ * @param{{client: HttpClient, sessionint: HttpWTSession, ourl: URL}} args
66
+ * @abstract
67
+ */
68
+ startUpConnection({ client, sessionint, ourl }) {
69
+ throw new Error('Implement createClient')
70
70
  }
71
71
 
72
72
  get reliability() {
73
- const session = sessions.get(this)
73
+ const session = this.sessionint
74
74
 
75
- if (session == null) {
75
+ if (!session) {
76
76
  // should never happen as session is only removed when this instance is garbage collected
77
77
  throw new Error('Http3WTSession was undefined')
78
78
  }
@@ -80,19 +80,25 @@ export class WebTransport {
80
80
  }
81
81
 
82
82
  get congestionControl() {
83
- const session = sessions.get(this)
83
+ const session = this.sessionint
84
84
 
85
- if (session == null) {
85
+ if (!session) {
86
86
  // should never happen as session is only removed when this instance is garbage collected
87
87
  throw new Error('Http3WTSession was undefined')
88
88
  }
89
89
  return session.congestionControl
90
90
  }
91
91
 
92
+ get supportsReliableOnly() {
93
+ throw new Error('Implement supportsReliableOnly')
94
+ // eslint-disable-next-line no-unreachable
95
+ return false
96
+ }
97
+
92
98
  getStats() {
93
- const session = sessions.get(this)
99
+ const session = this.sessionint
94
100
 
95
- if (session == null) {
101
+ if (!session) {
96
102
  // should never happen as session is only removed when this instance is garbage collected
97
103
  throw new Error('Http3WTSession was undefined')
98
104
  }
@@ -103,9 +109,9 @@ export class WebTransport {
103
109
  * @param {WebTransportCloseInfo} [closeinfo]
104
110
  */
105
111
  close(closeinfo) {
106
- const session = sessions.get(this)
112
+ const session = this.sessionint
107
113
 
108
- if (session == null) {
114
+ if (!session) {
109
115
  // should never happen as session is only removed when this instance is garbage collected
110
116
  throw new Error('Http3WTSession was undefined')
111
117
  }
@@ -114,9 +120,9 @@ export class WebTransport {
114
120
  }
115
121
 
116
122
  createBidirectionalStream() {
117
- const session = sessions.get(this)
123
+ const session = this.sessionint
118
124
 
119
- if (session == null) {
125
+ if (!session) {
120
126
  // should never happen as session is only removed when this instance is garbage collected
121
127
  throw new Error('Http3WTSession was undefined')
122
128
  }
@@ -125,9 +131,9 @@ export class WebTransport {
125
131
  }
126
132
 
127
133
  createUnidirectionalStream() {
128
- const session = sessions.get(this)
134
+ const session = this.sessionint
129
135
 
130
- if (session == null) {
136
+ if (!session) {
131
137
  // should never happen as session is only removed when this instance is garbage collected
132
138
  throw new Error('Http3WTSession was undefined')
133
139
  }
package/old_test/test.js CHANGED
@@ -5,19 +5,16 @@
5
5
  // this file runs various tests
6
6
 
7
7
  import { generateWebTransportCertificate } from '../test/fixtures/certificate.js'
8
- import { Http3Server, WebTransport, testcheck } from '../lib/index.js'
8
+ import { Http3Server, Http2Server, WebTransport } from '../lib/index.node.js'
9
9
  import { echoTestsConnection, runEchoServer } from './testsuite.js'
10
10
 
11
+ let http2 = false
12
+
13
+ if (process.argv.some((el) => el === 'http2')) {
14
+ http2 = true
15
+ }
16
+
11
17
  async function run() {
12
- setTimeout(() => {
13
- if (!testcheck()) {
14
- console.log('tests took too long, probably hanging')
15
- process.exit(1)
16
- } else {
17
- console.log('global event loop gone, everything alright')
18
- process.exit(0)
19
- }
20
- }, 50 * 1000)
21
18
  console.log('try connecting to server that does not exist')
22
19
  const badClient = new WebTransport('https://127.0.0.1:49823/echo', {
23
20
  serverCertificateHashes: [
@@ -57,18 +54,29 @@ async function run() {
57
54
  throw new Error('Certificate generation failed')
58
55
  }
59
56
 
60
- console.log('start Http3Server and startup echo tests')
57
+ console.log('start HttpServer and startup echo tests')
61
58
  // now ramp up the server
62
- const http3server = new Http3Server({
63
- port: 8080,
64
- host: '127.0.0.1',
65
- secret: 'mysecret',
66
- cert: certificate.cert, // unclear if it is the correct format
67
- privKey: certificate.private
68
- })
59
+ let httpserver
60
+ if (!http2) {
61
+ httpserver = new Http3Server({
62
+ port: 8080,
63
+ host: '127.0.0.1',
64
+ secret: 'mysecret',
65
+ cert: certificate.cert, // unclear if it is the correct format
66
+ privKey: certificate.private
67
+ })
68
+ } else {
69
+ httpserver = new Http2Server({
70
+ port: 8080,
71
+ host: '127.0.0.1',
72
+ secret: 'mysecret',
73
+ cert: certificate.cert, // unclear if it is the correct format
74
+ privKey: certificate.private
75
+ })
76
+ }
69
77
 
70
- http3server.startServer() // you can call destroy to remove the server
71
- runEchoServer(http3server)
78
+ httpserver.startServer() // you can call destroy to remove the server
79
+ runEchoServer(httpserver)
72
80
 
73
81
  console.log('server started now wait 2 seconds')
74
82
 
@@ -83,16 +91,10 @@ async function run() {
83
91
  })
84
92
  client.closed
85
93
  .then(() => {
86
- console.log('The HTTP/3 connection to ', url, 'closed gracefully.')
94
+ console.log('The HTTP connection to ', url, 'closed gracefully.')
87
95
  })
88
96
  .catch((error) => {
89
- console.error(
90
- 'The HTTP/3 connection to',
91
- url,
92
- 'closed due to ',
93
- error,
94
- '.'
95
- )
97
+ console.error('The HTTP connection to', url, 'closed due to ', error, '.')
96
98
  })
97
99
  console.log('wait for client to be ready')
98
100
  await client.ready
@@ -114,7 +116,7 @@ async function run() {
114
116
 
115
117
  console.log('now stop server')
116
118
 
117
- http3server.stopServer()
119
+ httpserver.stopServer()
118
120
  console.log('tests finished!')
119
121
  }
120
122
  run()
@@ -77,7 +77,7 @@ export async function datagramEchoTest(session) {
77
77
  }
78
78
 
79
79
  /**
80
- * @param {import('../lib').Http3Server} server
80
+ * @param {import('../lib').Http3Server|import('../lib').Http2Server} server
81
81
  */
82
82
  export async function runEchoServer(server) {
83
83
  try {