@libp2p/webtransport 3.0.4-d30f09f2 → 3.0.4-d9948596
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.
- package/dist/index.min.js +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +101 -43
- package/dist/src/index.js.map +1 -1
- package/package.json +5 -5
- package/src/index.ts +123 -46
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAuE,MAAM,6BAA6B,CAAA;AAQjI,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAKvD,OAAO,CAAC,MAAM,CAAC;IACb,IAAI,YAAY,EAAE,GAAG,CAAA;CACtB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAuE,MAAM,6BAA6B,CAAA;AAQjI,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAKvD,OAAO,CAAC,MAAM,CAAC;IACb,IAAI,YAAY,EAAE,GAAG,CAAA;CACtB;AAcD,MAAM,WAAW,gBAAgB;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAA;CACf;AA+RD,wBAAgB,YAAY,CAAE,IAAI,GAAE,gBAAqB,GAAG,CAAC,UAAU,EAAE,sBAAsB,KAAK,SAAS,CAE5G"}
|
package/dist/src/index.js
CHANGED
|
@@ -19,6 +19,7 @@ class WebTransportTransport {
|
|
|
19
19
|
[Symbol.toStringTag] = '@libp2p/webtransport';
|
|
20
20
|
[symbol] = true;
|
|
21
21
|
async dial(ma, options) {
|
|
22
|
+
options?.signal?.throwIfAborted();
|
|
22
23
|
log('dialing %s', ma);
|
|
23
24
|
const localPeer = this.components.peerId;
|
|
24
25
|
if (localPeer === undefined) {
|
|
@@ -26,54 +27,108 @@ class WebTransportTransport {
|
|
|
26
27
|
}
|
|
27
28
|
options = options ?? {};
|
|
28
29
|
const { url, certhashes, remotePeer } = parseMultiaddr(ma);
|
|
29
|
-
if (certhashes.length === 0) {
|
|
30
|
-
throw new Error('Expected multiaddr to contain certhashes');
|
|
31
|
-
}
|
|
32
|
-
const wt = new WebTransport(`${url}/.well-known/libp2p-webtransport?type=noise`, {
|
|
33
|
-
serverCertificateHashes: certhashes.map(certhash => ({
|
|
34
|
-
algorithm: 'sha-256',
|
|
35
|
-
value: certhash.digest
|
|
36
|
-
}))
|
|
37
|
-
});
|
|
38
|
-
wt.closed.catch((error) => {
|
|
39
|
-
log.error('WebTransport transport closed due to:', error);
|
|
40
|
-
});
|
|
41
|
-
await wt.ready;
|
|
42
30
|
if (remotePeer == null) {
|
|
43
31
|
throw new Error('Need a target peerid');
|
|
44
32
|
}
|
|
45
|
-
if (
|
|
46
|
-
throw new Error('
|
|
33
|
+
if (certhashes.length === 0) {
|
|
34
|
+
throw new Error('Expected multiaddr to contain certhashes');
|
|
47
35
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
await wt.close();
|
|
52
|
-
},
|
|
53
|
-
abort: (err) => {
|
|
54
|
-
log('Aborting webtransport with err:', err);
|
|
55
|
-
wt.close();
|
|
56
|
-
},
|
|
57
|
-
remoteAddr: ma,
|
|
58
|
-
timeline: {
|
|
59
|
-
open: Date.now()
|
|
60
|
-
},
|
|
61
|
-
// This connection is never used directly since webtransport supports native streams.
|
|
62
|
-
...inertDuplex()
|
|
63
|
-
};
|
|
64
|
-
wt.closed.catch((err) => {
|
|
65
|
-
log.error('WebTransport connection closed:', err);
|
|
66
|
-
// This is how we specify the connection is closed and shouldn't be used.
|
|
67
|
-
maConn.timeline.close = Date.now();
|
|
68
|
-
});
|
|
36
|
+
let abortListener;
|
|
37
|
+
let maConn;
|
|
38
|
+
let cleanUpWTSession = () => { };
|
|
69
39
|
try {
|
|
40
|
+
let closed = false;
|
|
41
|
+
const wt = new WebTransport(`${url}/.well-known/libp2p-webtransport?type=noise`, {
|
|
42
|
+
serverCertificateHashes: certhashes.map(certhash => ({
|
|
43
|
+
algorithm: 'sha-256',
|
|
44
|
+
value: certhash.digest
|
|
45
|
+
}))
|
|
46
|
+
});
|
|
47
|
+
cleanUpWTSession = (closeInfo) => {
|
|
48
|
+
try {
|
|
49
|
+
if (maConn != null) {
|
|
50
|
+
if (maConn.timeline.close != null) {
|
|
51
|
+
// already closed session
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
// This is how we specify the connection is closed and shouldn't be used.
|
|
55
|
+
maConn.timeline.close = Date.now();
|
|
56
|
+
}
|
|
57
|
+
if (closed) {
|
|
58
|
+
// already closed session
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
wt.close(closeInfo);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
log.error('error closing wt session', err);
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
closed = true;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
// this promise resolves/throws when the session is closed or failed to init
|
|
71
|
+
wt.closed
|
|
72
|
+
.then(async () => {
|
|
73
|
+
await maConn?.close();
|
|
74
|
+
})
|
|
75
|
+
.catch((err) => {
|
|
76
|
+
log.error('error on remote wt session close', err);
|
|
77
|
+
maConn?.abort(err);
|
|
78
|
+
})
|
|
79
|
+
.finally(() => {
|
|
80
|
+
// if we never got as far as creating the maConn, just clean up the session
|
|
81
|
+
if (maConn == null) {
|
|
82
|
+
cleanUpWTSession();
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
// if the dial is aborted before we are ready, close the WebTransport session
|
|
86
|
+
abortListener = () => {
|
|
87
|
+
if (abortListener != null) {
|
|
88
|
+
options.signal?.removeEventListener('abort', abortListener);
|
|
89
|
+
}
|
|
90
|
+
cleanUpWTSession();
|
|
91
|
+
};
|
|
92
|
+
options.signal?.addEventListener('abort', abortListener);
|
|
93
|
+
await wt.ready;
|
|
94
|
+
if (!await this.authenticateWebTransport(wt, localPeer, remotePeer, certhashes)) {
|
|
95
|
+
throw new Error('Failed to authenticate webtransport');
|
|
96
|
+
}
|
|
97
|
+
maConn = {
|
|
98
|
+
close: async (options) => {
|
|
99
|
+
log('Closing webtransport');
|
|
100
|
+
cleanUpWTSession();
|
|
101
|
+
},
|
|
102
|
+
abort: (err) => {
|
|
103
|
+
log('aborting webtransport due to passed err', err);
|
|
104
|
+
cleanUpWTSession({
|
|
105
|
+
closeCode: 0,
|
|
106
|
+
reason: err.message
|
|
107
|
+
});
|
|
108
|
+
},
|
|
109
|
+
remoteAddr: ma,
|
|
110
|
+
timeline: {
|
|
111
|
+
open: Date.now()
|
|
112
|
+
},
|
|
113
|
+
// This connection is never used directly since webtransport supports native streams.
|
|
114
|
+
...inertDuplex()
|
|
115
|
+
};
|
|
70
116
|
options?.signal?.throwIfAborted();
|
|
117
|
+
return await options.upgrader.upgradeOutbound(maConn, { skipEncryption: true, muxerFactory: this.webtransportMuxer(wt, cleanUpWTSession), skipProtection: true });
|
|
71
118
|
}
|
|
72
|
-
catch (
|
|
73
|
-
|
|
74
|
-
|
|
119
|
+
catch (err) {
|
|
120
|
+
log.error('caught wt session err', err);
|
|
121
|
+
cleanUpWTSession({
|
|
122
|
+
closeCode: 0,
|
|
123
|
+
reason: err.message
|
|
124
|
+
});
|
|
125
|
+
throw err;
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
if (abortListener != null) {
|
|
129
|
+
options.signal?.removeEventListener('abort', abortListener);
|
|
130
|
+
}
|
|
75
131
|
}
|
|
76
|
-
return options.upgrader.upgradeOutbound(maConn, { skipEncryption: true, muxerFactory: this.webtransportMuxer(wt), skipProtection: true });
|
|
77
132
|
}
|
|
78
133
|
async authenticateWebTransport(wt, localPeer, remotePeer, certhashes) {
|
|
79
134
|
const stream = await wt.createBidirectionalStream();
|
|
@@ -113,7 +168,7 @@ class WebTransportTransport {
|
|
|
113
168
|
}
|
|
114
169
|
return true;
|
|
115
170
|
}
|
|
116
|
-
webtransportMuxer(wt) {
|
|
171
|
+
webtransportMuxer(wt, cleanUpWTSession) {
|
|
117
172
|
let streamIDCounter = 0;
|
|
118
173
|
const config = this.config;
|
|
119
174
|
return {
|
|
@@ -165,11 +220,14 @@ class WebTransportTransport {
|
|
|
165
220
|
*/
|
|
166
221
|
close: async (options) => {
|
|
167
222
|
log('Closing webtransport muxer');
|
|
168
|
-
|
|
223
|
+
cleanUpWTSession();
|
|
169
224
|
},
|
|
170
225
|
abort: (err) => {
|
|
171
226
|
log('Aborting webtransport muxer with err:', err);
|
|
172
|
-
|
|
227
|
+
cleanUpWTSession({
|
|
228
|
+
closeCode: 0,
|
|
229
|
+
reason: err.message
|
|
230
|
+
});
|
|
173
231
|
},
|
|
174
232
|
// This stream muxer is webtransport native. Therefore it doesn't plug in with any other duplex.
|
|
175
233
|
...inertDuplex()
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAC/C,OAAO,EAAkB,MAAM,EAA+D,MAAM,6BAA6B,CAAA;AACjI,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AACvC,OAAO,EAAqC,MAAM,yBAAyB,CAAA;AAC3E,OAAO,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libp2p/webtransport",
|
|
3
|
-
"version": "3.0.4-
|
|
3
|
+
"version": "3.0.4-d9948596",
|
|
4
4
|
"description": "JavaScript implementation of the WebTransport module that libp2p uses and that implements the interface-transport spec",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/transport-webtransport#readme",
|
|
@@ -65,9 +65,9 @@
|
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
67
|
"@chainsafe/libp2p-noise": "^13.0.0",
|
|
68
|
-
"@libp2p/interface": "0.1.2-
|
|
69
|
-
"@libp2p/logger": "3.0.2-
|
|
70
|
-
"@libp2p/peer-id": "3.0.2-
|
|
68
|
+
"@libp2p/interface": "0.1.2-d9948596",
|
|
69
|
+
"@libp2p/logger": "3.0.2-d9948596",
|
|
70
|
+
"@libp2p/peer-id": "3.0.2-d9948596",
|
|
71
71
|
"@multiformats/multiaddr": "^12.1.5",
|
|
72
72
|
"it-stream-types": "^2.0.1",
|
|
73
73
|
"multiformats": "^12.0.1",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
78
|
"aegir": "^40.0.8",
|
|
79
|
-
"libp2p": "0.46.4-
|
|
79
|
+
"libp2p": "0.46.4-d9948596",
|
|
80
80
|
"p-defer": "^4.0.0"
|
|
81
81
|
},
|
|
82
82
|
"browser": {
|
package/src/index.ts
CHANGED
|
@@ -16,6 +16,16 @@ declare global {
|
|
|
16
16
|
var WebTransport: any
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
// https://www.w3.org/TR/webtransport/#web-transport-close-info
|
|
20
|
+
interface WebTransportCloseInfo {
|
|
21
|
+
closeCode: number
|
|
22
|
+
reason: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface WebTransportSessionCleanup {
|
|
26
|
+
(closeInfo?: WebTransportCloseInfo): void
|
|
27
|
+
}
|
|
28
|
+
|
|
19
29
|
const log = logger('libp2p:webtransport')
|
|
20
30
|
|
|
21
31
|
export interface WebTransportInit {
|
|
@@ -42,6 +52,8 @@ class WebTransportTransport implements Transport {
|
|
|
42
52
|
readonly [symbol] = true
|
|
43
53
|
|
|
44
54
|
async dial (ma: Multiaddr, options: DialOptions): Promise<Connection> {
|
|
55
|
+
options?.signal?.throwIfAborted()
|
|
56
|
+
|
|
45
57
|
log('dialing %s', ma)
|
|
46
58
|
const localPeer = this.components.peerId
|
|
47
59
|
if (localPeer === undefined) {
|
|
@@ -52,60 +64,122 @@ class WebTransportTransport implements Transport {
|
|
|
52
64
|
|
|
53
65
|
const { url, certhashes, remotePeer } = parseMultiaddr(ma)
|
|
54
66
|
|
|
55
|
-
if (certhashes.length === 0) {
|
|
56
|
-
throw new Error('Expected multiaddr to contain certhashes')
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const wt = new WebTransport(`${url}/.well-known/libp2p-webtransport?type=noise`, {
|
|
60
|
-
serverCertificateHashes: certhashes.map(certhash => ({
|
|
61
|
-
algorithm: 'sha-256',
|
|
62
|
-
value: certhash.digest
|
|
63
|
-
}))
|
|
64
|
-
})
|
|
65
|
-
wt.closed.catch((error: Error) => {
|
|
66
|
-
log.error('WebTransport transport closed due to:', error)
|
|
67
|
-
})
|
|
68
|
-
await wt.ready
|
|
69
|
-
|
|
70
67
|
if (remotePeer == null) {
|
|
71
68
|
throw new Error('Need a target peerid')
|
|
72
69
|
}
|
|
73
70
|
|
|
74
|
-
if (
|
|
75
|
-
throw new Error('
|
|
71
|
+
if (certhashes.length === 0) {
|
|
72
|
+
throw new Error('Expected multiaddr to contain certhashes')
|
|
76
73
|
}
|
|
77
74
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
log('Closing webtransport')
|
|
81
|
-
await wt.close()
|
|
82
|
-
},
|
|
83
|
-
abort: (err: Error) => {
|
|
84
|
-
log('Aborting webtransport with err:', err)
|
|
85
|
-
wt.close()
|
|
86
|
-
},
|
|
87
|
-
remoteAddr: ma,
|
|
88
|
-
timeline: {
|
|
89
|
-
open: Date.now()
|
|
90
|
-
},
|
|
91
|
-
// This connection is never used directly since webtransport supports native streams.
|
|
92
|
-
...inertDuplex()
|
|
93
|
-
}
|
|
75
|
+
let abortListener: (() => void) | undefined
|
|
76
|
+
let maConn: MultiaddrConnection | undefined
|
|
94
77
|
|
|
95
|
-
|
|
96
|
-
log.error('WebTransport connection closed:', err)
|
|
97
|
-
// This is how we specify the connection is closed and shouldn't be used.
|
|
98
|
-
maConn.timeline.close = Date.now()
|
|
99
|
-
})
|
|
78
|
+
let cleanUpWTSession: (closeInfo?: WebTransportCloseInfo) => void = () => {}
|
|
100
79
|
|
|
101
80
|
try {
|
|
81
|
+
let closed = false
|
|
82
|
+
const wt = new WebTransport(`${url}/.well-known/libp2p-webtransport?type=noise`, {
|
|
83
|
+
serverCertificateHashes: certhashes.map(certhash => ({
|
|
84
|
+
algorithm: 'sha-256',
|
|
85
|
+
value: certhash.digest
|
|
86
|
+
}))
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
cleanUpWTSession = (closeInfo?: WebTransportCloseInfo) => {
|
|
90
|
+
try {
|
|
91
|
+
if (maConn != null) {
|
|
92
|
+
if (maConn.timeline.close != null) {
|
|
93
|
+
// already closed session
|
|
94
|
+
return
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// This is how we specify the connection is closed and shouldn't be used.
|
|
98
|
+
maConn.timeline.close = Date.now()
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (closed) {
|
|
102
|
+
// already closed session
|
|
103
|
+
return
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
wt.close(closeInfo)
|
|
107
|
+
} catch (err) {
|
|
108
|
+
log.error('error closing wt session', err)
|
|
109
|
+
} finally {
|
|
110
|
+
closed = true
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// this promise resolves/throws when the session is closed or failed to init
|
|
115
|
+
wt.closed
|
|
116
|
+
.then(async () => {
|
|
117
|
+
await maConn?.close()
|
|
118
|
+
})
|
|
119
|
+
.catch((err: Error) => {
|
|
120
|
+
log.error('error on remote wt session close', err)
|
|
121
|
+
maConn?.abort(err)
|
|
122
|
+
})
|
|
123
|
+
.finally(() => {
|
|
124
|
+
// if we never got as far as creating the maConn, just clean up the session
|
|
125
|
+
if (maConn == null) {
|
|
126
|
+
cleanUpWTSession()
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
// if the dial is aborted before we are ready, close the WebTransport session
|
|
131
|
+
abortListener = () => {
|
|
132
|
+
if (abortListener != null) {
|
|
133
|
+
options.signal?.removeEventListener('abort', abortListener)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
cleanUpWTSession()
|
|
137
|
+
}
|
|
138
|
+
options.signal?.addEventListener('abort', abortListener)
|
|
139
|
+
|
|
140
|
+
await wt.ready
|
|
141
|
+
|
|
142
|
+
if (!await this.authenticateWebTransport(wt, localPeer, remotePeer, certhashes)) {
|
|
143
|
+
throw new Error('Failed to authenticate webtransport')
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
maConn = {
|
|
147
|
+
close: async (options?: AbortOptions) => {
|
|
148
|
+
log('Closing webtransport')
|
|
149
|
+
cleanUpWTSession()
|
|
150
|
+
},
|
|
151
|
+
abort: (err: Error) => {
|
|
152
|
+
log('aborting webtransport due to passed err', err)
|
|
153
|
+
cleanUpWTSession({
|
|
154
|
+
closeCode: 0,
|
|
155
|
+
reason: err.message
|
|
156
|
+
})
|
|
157
|
+
},
|
|
158
|
+
remoteAddr: ma,
|
|
159
|
+
timeline: {
|
|
160
|
+
open: Date.now()
|
|
161
|
+
},
|
|
162
|
+
// This connection is never used directly since webtransport supports native streams.
|
|
163
|
+
...inertDuplex()
|
|
164
|
+
}
|
|
165
|
+
|
|
102
166
|
options?.signal?.throwIfAborted()
|
|
103
|
-
} catch (e) {
|
|
104
|
-
wt.close()
|
|
105
|
-
throw e
|
|
106
|
-
}
|
|
107
167
|
|
|
108
|
-
|
|
168
|
+
return await options.upgrader.upgradeOutbound(maConn, { skipEncryption: true, muxerFactory: this.webtransportMuxer(wt, cleanUpWTSession), skipProtection: true })
|
|
169
|
+
} catch (err: any) {
|
|
170
|
+
log.error('caught wt session err', err)
|
|
171
|
+
|
|
172
|
+
cleanUpWTSession({
|
|
173
|
+
closeCode: 0,
|
|
174
|
+
reason: err.message
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
throw err
|
|
178
|
+
} finally {
|
|
179
|
+
if (abortListener != null) {
|
|
180
|
+
options.signal?.removeEventListener('abort', abortListener)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
109
183
|
}
|
|
110
184
|
|
|
111
185
|
async authenticateWebTransport (wt: InstanceType<typeof WebTransport>, localPeer: PeerId, remotePeer: PeerId, certhashes: Array<MultihashDigest<number>>): Promise<boolean> {
|
|
@@ -156,7 +230,7 @@ class WebTransportTransport implements Transport {
|
|
|
156
230
|
return true
|
|
157
231
|
}
|
|
158
232
|
|
|
159
|
-
webtransportMuxer (wt: InstanceType<typeof WebTransport
|
|
233
|
+
webtransportMuxer (wt: InstanceType<typeof WebTransport>, cleanUpWTSession: WebTransportSessionCleanup): StreamMuxerFactory {
|
|
160
234
|
let streamIDCounter = 0
|
|
161
235
|
const config = this.config
|
|
162
236
|
return {
|
|
@@ -217,11 +291,14 @@ class WebTransportTransport implements Transport {
|
|
|
217
291
|
*/
|
|
218
292
|
close: async (options?: AbortOptions) => {
|
|
219
293
|
log('Closing webtransport muxer')
|
|
220
|
-
|
|
294
|
+
cleanUpWTSession()
|
|
221
295
|
},
|
|
222
296
|
abort: (err: Error) => {
|
|
223
297
|
log('Aborting webtransport muxer with err:', err)
|
|
224
|
-
|
|
298
|
+
cleanUpWTSession({
|
|
299
|
+
closeCode: 0,
|
|
300
|
+
reason: err.message
|
|
301
|
+
})
|
|
225
302
|
},
|
|
226
303
|
// This stream muxer is webtransport native. Therefore it doesn't plug in with any other duplex.
|
|
227
304
|
...inertDuplex()
|