@fails-components/webtransport 0.2.2 → 0.3.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.
- package/CMakeLists.txt +3 -0
- package/dist/lib/client.d.ts +7 -3
- package/dist/lib/client.d.ts.map +1 -1
- package/dist/lib/dom.d.ts +15 -4
- package/dist/lib/dom.d.ts.map +1 -1
- package/dist/lib/error.d.ts +8 -0
- package/dist/lib/error.d.ts.map +1 -0
- package/dist/lib/event-loop.d.ts +4 -2
- package/dist/lib/event-loop.d.ts.map +1 -1
- package/dist/lib/native.d.ts.map +1 -1
- package/dist/lib/server.d.ts +5 -2
- package/dist/lib/server.d.ts.map +1 -1
- package/dist/lib/session.d.ts +36 -23
- package/dist/lib/session.d.ts.map +1 -1
- package/dist/lib/stream.d.ts +15 -4
- package/dist/lib/stream.d.ts.map +1 -1
- package/dist/lib/transport.d.ts +12 -3
- package/dist/lib/transport.d.ts.map +1 -1
- package/dist/lib/types.d.ts +43 -4
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/utils.d.ts +5 -0
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/webtransport.d.ts +11 -21
- package/dist/lib/webtransport.d.ts.map +1 -1
- package/dist/test/datagrams.spec.d.ts.map +1 -1
- package/dist/test/event-loop.node.d.ts +2 -0
- package/dist/test/event-loop.node.d.ts.map +1 -0
- package/dist/test/fixtures/chai.d.ts.map +1 -1
- package/dist/test/fixtures/known-bytes.d.ts +6 -0
- package/dist/test/fixtures/known-bytes.d.ts.map +1 -0
- package/dist/test/fixtures/read-cert-hash.d.ts +6 -0
- package/dist/test/fixtures/read-cert-hash.d.ts.map +1 -0
- package/dist/test/fixtures/read-stream.d.ts +10 -1
- package/dist/test/fixtures/read-stream.d.ts.map +1 -1
- package/dist/test/fixtures/reader-value.d.ts +16 -1
- package/dist/test/fixtures/reader-value.d.ts.map +1 -1
- package/dist/test/fixtures/server.d.ts +0 -5
- package/dist/test/fixtures/server.d.ts.map +1 -1
- package/dist/test/fixtures/webtransport.browser.d.ts +3 -0
- package/dist/test/fixtures/webtransport.browser.d.ts.map +1 -0
- package/dist/test/fixtures/webtransport.d.ts +3 -0
- package/dist/test/fixtures/webtransport.d.ts.map +1 -0
- package/dist/test/fixtures/write-stream.d.ts.map +1 -1
- package/dist/test/index.d.ts +2 -0
- package/dist/test/index.d.ts.map +1 -0
- package/dist/test/session.spec.d.ts +5 -0
- package/dist/test/session.spec.d.ts.map +1 -0
- package/dist/test/unidirectional-streams.spec.d.ts +1 -4
- package/dist/test/unidirectional-streams.spec.d.ts.map +1 -1
- package/lib/client.js +57 -43
- package/lib/dom.ts +18 -4
- package/lib/error.js +10 -0
- package/lib/event-loop.js +8 -5
- package/lib/native.js +4 -1
- package/lib/server.js +18 -10
- package/lib/session.js +145 -32
- package/lib/stream.js +51 -22
- package/lib/transport.js +48 -10
- package/lib/types.ts +53 -5
- package/lib/utils.js +13 -0
- package/lib/webtransport.js +10 -18
- package/{test → old_test}/echoserver.js +1 -2
- package/{test → old_test}/test.js +5 -3
- package/package.json +16 -5
- package/readme.md +64 -0
- package/src/http3client.cc +2 -2
- package/src/http3dispatcher.cc +3 -2
- package/src/http3dispatcher.h +2 -1
- package/src/http3eventloop.cc +106 -2
- package/src/http3eventloop.h +13 -0
- package/src/http3wtsessionvisitor.cc +2 -0
- package/src/http3wtsessionvisitor.h +41 -1
- package/test/bidirectional-streams.spec.js +41 -97
- package/test/datagrams.spec.js +46 -99
- package/test/fixtures/chai.js +2 -0
- package/test/fixtures/known-bytes.js +15 -0
- package/test/fixtures/read-cert-hash.js +7 -0
- package/test/fixtures/read-stream.js +5 -0
- package/test/fixtures/reader-value.js +32 -0
- package/test/fixtures/server.js +237 -21
- package/test/fixtures/webtransport.browser.js +2 -0
- package/test/fixtures/webtransport.js +3 -0
- package/test/fixtures/write-stream.js +8 -1
- package/test/index.js +87 -0
- package/test/session.spec.js +159 -0
- package/test/unidirectional-streams.spec.js +67 -138
- package/tsconfig.json +0 -1
- package/dist/test/echoclient.d.ts +0 -2
- package/dist/test/echoclient.d.ts.map +0 -1
- package/dist/test/echoserver.d.ts +0 -2
- package/dist/test/echoserver.d.ts.map +0 -1
- package/dist/test/event-loop.spec.d.ts +0 -2
- package/dist/test/event-loop.spec.d.ts.map +0 -1
- package/dist/test/test.d.ts +0 -2
- package/dist/test/test.d.ts.map +0 -1
- package/dist/test/testsuite.d.ts +0 -25
- package/dist/test/testsuite.d.ts.map +0 -1
- package/platform/base/strings/utf_ostream_operators.h +0 -5
- /package/{test → old_test}/echoclient.js +0 -0
- /package/{test → old_test}/testsuite.js +0 -0
- /package/test/{event-loop.spec.js → event-loop.node.js} +0 -0
package/lib/utils.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import debug from 'debug'
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* @template {unknown} T
|
|
3
5
|
* @returns {import('./types').Deferred<T>}
|
|
@@ -20,3 +22,14 @@ export function defer() {
|
|
|
20
22
|
reject: rej
|
|
21
23
|
}
|
|
22
24
|
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {string} name
|
|
28
|
+
* @returns {import('./types').Logger}
|
|
29
|
+
*/
|
|
30
|
+
export function logger(name) {
|
|
31
|
+
return Object.assign(debug(name), {
|
|
32
|
+
error: debug(`${name}:error`),
|
|
33
|
+
trace: process.env.DEBUG_TRACE ? debug(`${name}:trace`) : () => {}
|
|
34
|
+
})
|
|
35
|
+
}
|
package/lib/webtransport.js
CHANGED
|
@@ -10,6 +10,11 @@ const sessions = new WeakMap()
|
|
|
10
10
|
* @typedef {import('./dom').WebTransportReceiveStream} WebTransportReceiveStream
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* @template T
|
|
15
|
+
* @typedef {import('node:stream/web').ReadableStream<T>} ReadableStream<T>
|
|
16
|
+
*/
|
|
17
|
+
|
|
13
18
|
/**
|
|
14
19
|
* @typedef {import('./dom').WebTransport} WebTransportInterface
|
|
15
20
|
*
|
|
@@ -29,11 +34,11 @@ export class WebTransport {
|
|
|
29
34
|
throw new Error('URL is not supported for webtransport')
|
|
30
35
|
}
|
|
31
36
|
|
|
32
|
-
const
|
|
37
|
+
const host = ourl.hostname
|
|
33
38
|
let port = ourl.port
|
|
34
39
|
if (port === '') port = '443'
|
|
35
40
|
|
|
36
|
-
const client = new Http3Client({
|
|
41
|
+
const client = new Http3Client({ host, port, ...args })
|
|
37
42
|
|
|
38
43
|
const sessionint = new Http3WTSession({
|
|
39
44
|
/* object: args.session, */
|
|
@@ -49,7 +54,6 @@ export class WebTransport {
|
|
|
49
54
|
/** @type {ReadableStream<WebTransportBidirectionalStream>} */
|
|
50
55
|
this.incomingBidirectionalStreams = sessionint.incomingBidirectionalStreams
|
|
51
56
|
|
|
52
|
-
/** @type {ReadableStream<WebTransportReceiveStream>} */
|
|
53
57
|
this.incomingUnidirectionalStreams =
|
|
54
58
|
sessionint.incomingUnidirectionalStreams
|
|
55
59
|
|
|
@@ -57,23 +61,11 @@ export class WebTransport {
|
|
|
57
61
|
|
|
58
62
|
client
|
|
59
63
|
.handleConnection()
|
|
60
|
-
.then(() =>
|
|
61
|
-
client.quicconnected
|
|
62
|
-
?.then(() => {
|
|
63
|
-
return client.createWTSession(sessionint, ourl.pathname)
|
|
64
|
-
})
|
|
65
|
-
.catch((err) => {
|
|
66
|
-
sessionint.readyReject(
|
|
67
|
-
new Error('Establishing session failed ' + err)
|
|
68
|
-
)
|
|
69
|
-
console.log('Establishing session failed ' + err)
|
|
70
|
-
client.closeHookSession()
|
|
71
|
-
})
|
|
72
|
-
})
|
|
64
|
+
.then(() => client.createWTSession(sessionint, ourl.pathname))
|
|
73
65
|
.catch((error) => {
|
|
74
|
-
sessionint.readyReject(new Error('Quic connection failed ' + error))
|
|
75
|
-
console.log('Quic connection failed ' + error)
|
|
76
66
|
client.closeHookSession()
|
|
67
|
+
sessionint.readyReject(error)
|
|
68
|
+
sessionint.closedReject(error)
|
|
77
69
|
})
|
|
78
70
|
}
|
|
79
71
|
|
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
import { Http3Server } from '../lib/index.js'
|
|
6
6
|
import { runEchoServer } from './testsuite.js'
|
|
7
7
|
import { existsSync, readFileSync, writeFile } from 'node:fs'
|
|
8
|
-
|
|
9
|
-
import { generateWebTransportCertificate } from './fixtures/certificate.js'
|
|
8
|
+
import { generateWebTransportCertificate } from '../test/fixtures/certificate.js'
|
|
10
9
|
|
|
11
10
|
let certificate = null
|
|
12
11
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
// this file runs various tests
|
|
6
6
|
|
|
7
|
-
import { generateWebTransportCertificate } from '
|
|
7
|
+
import { generateWebTransportCertificate } from '../test/fixtures/certificate.js'
|
|
8
8
|
import { Http3Server, WebTransport, testcheck } from '../lib/index.js'
|
|
9
9
|
import { echoTestsConnection, runEchoServer } from './testsuite.js'
|
|
10
10
|
|
|
@@ -30,7 +30,7 @@ async function run() {
|
|
|
30
30
|
}
|
|
31
31
|
]
|
|
32
32
|
})
|
|
33
|
-
await badClient.ready
|
|
33
|
+
await Promise.all([badClient.ready, badClient.closed])
|
|
34
34
|
.then(() => {
|
|
35
35
|
console.error('Successfully connected to a non-running server?!')
|
|
36
36
|
process.exit(1)
|
|
@@ -67,8 +67,8 @@ async function run() {
|
|
|
67
67
|
privKey: certificate.private
|
|
68
68
|
})
|
|
69
69
|
|
|
70
|
-
runEchoServer(http3server)
|
|
71
70
|
http3server.startServer() // you can call destroy to remove the server
|
|
71
|
+
runEchoServer(http3server)
|
|
72
72
|
|
|
73
73
|
console.log('server started now wait 2 seconds')
|
|
74
74
|
|
|
@@ -98,6 +98,8 @@ async function run() {
|
|
|
98
98
|
await client.ready
|
|
99
99
|
console.log('client is ready')
|
|
100
100
|
await echoTestsConnection(client)
|
|
101
|
+
console.log('Test if getStats works')
|
|
102
|
+
console.log('getStats returned', await client.getStats())
|
|
101
103
|
console.log('client test finished, now close the client but wait 2 seconds')
|
|
102
104
|
|
|
103
105
|
await new Promise((resolve) => setTimeout(resolve, 2000))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fails-components/webtransport",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "A component to add webtransport support (server and client) to node.js using libquiche",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib/index.js",
|
|
@@ -11,15 +11,17 @@
|
|
|
11
11
|
"types": "./dist/lib/index.d.ts",
|
|
12
12
|
"scripts": {
|
|
13
13
|
"start": "node test/echoserver.js",
|
|
14
|
-
"test": "
|
|
15
|
-
"
|
|
14
|
+
"test": "npm run test:node && npm run test:chromium",
|
|
15
|
+
"test:node": "node test/index.js node",
|
|
16
|
+
"test:chromium": "node test/index.js chromium",
|
|
17
|
+
"oldtest": "node old_test/test.js",
|
|
16
18
|
"install": "node build.js install",
|
|
17
19
|
"build": "node build.js build",
|
|
18
20
|
"rebuild": "node build.js rebuild",
|
|
19
21
|
"rebuild-debug": "node build.js rebuild-debug -D",
|
|
20
22
|
"build-debug": "node build.js build-debug",
|
|
21
23
|
"types": "tsc",
|
|
22
|
-
"lint": "eslint lib test"
|
|
24
|
+
"lint": "eslint lib test old_test"
|
|
23
25
|
},
|
|
24
26
|
"repository": {
|
|
25
27
|
"type": "git",
|
|
@@ -35,7 +37,9 @@
|
|
|
35
37
|
},
|
|
36
38
|
"homepage": "https://github.com/fails-components/webtransport#readme",
|
|
37
39
|
"dependencies": {
|
|
40
|
+
"@types/debug": "^4.1.7",
|
|
38
41
|
"bindings": "^1.5.0",
|
|
42
|
+
"debug": "^4.3.4",
|
|
39
43
|
"node-addon-api": "^4.3.0",
|
|
40
44
|
"prebuild-install": "^7.1.1"
|
|
41
45
|
},
|
|
@@ -43,10 +47,12 @@
|
|
|
43
47
|
"@babel/core": "^7.17.10",
|
|
44
48
|
"@babel/eslint-parser": "^7.17.0",
|
|
45
49
|
"@types/chai": "^4.3.3",
|
|
50
|
+
"@types/chai-as-promised": "^7.1.5",
|
|
46
51
|
"@types/dirty-chai": "^2.0.2",
|
|
47
52
|
"@types/mocha": "^10.0.0",
|
|
48
53
|
"@types/node": "^18.15.3",
|
|
49
54
|
"chai": "^4.3.6",
|
|
55
|
+
"chai-as-promised": "^7.1.1",
|
|
50
56
|
"cmake-js": "^6.3.2",
|
|
51
57
|
"dirty-chai": "^2.0.1",
|
|
52
58
|
"eslint": "^7.32.0",
|
|
@@ -57,15 +63,20 @@
|
|
|
57
63
|
"eslint-plugin-prettier": "^3.4.1",
|
|
58
64
|
"eslint-plugin-promise": "^4.3.1",
|
|
59
65
|
"eslint-plugin-standard": "^4.1.0",
|
|
66
|
+
"execa": "^6.1.0",
|
|
60
67
|
"mocha": "^10.1.0",
|
|
61
68
|
"node-forge": "^1.3.1",
|
|
69
|
+
"playwright-test": "^12.3.4",
|
|
62
70
|
"prettier": "^2.4.1",
|
|
63
|
-
"typescript": "4.8.4",
|
|
71
|
+
"typescript": "^4.8.4",
|
|
64
72
|
"uint8arrays": "^4.0.2"
|
|
65
73
|
},
|
|
66
74
|
"binary": {
|
|
67
75
|
"napi_versions": [
|
|
68
76
|
6
|
|
69
77
|
]
|
|
78
|
+
},
|
|
79
|
+
"browser": {
|
|
80
|
+
"./test/fixtures/webtransport.js": "./test/fixtures/webtransport.browser.js"
|
|
70
81
|
}
|
|
71
82
|
}
|
package/readme.md
CHANGED
|
@@ -85,3 +85,67 @@ The WebTransport client only supports certification validation using fingerprint
|
|
|
85
85
|
* [outgoingMaxAge](https://www.w3.org/TR/webtransport/#dom-webtransportdatagramduplexstream-outgoingmaxage)
|
|
86
86
|
* [incomingHighWaterMark](https://www.w3.org/TR/webtransport/#dom-webtransportdatagramduplexstream-incominghighwatermark)
|
|
87
87
|
* [outgoingHighWaterMark](https://www.w3.org/TR/webtransport/#dom-webtransportdatagramduplexstream-outgoinghighwatermark)
|
|
88
|
+
|
|
89
|
+
## Development notes
|
|
90
|
+
|
|
91
|
+
### Tests
|
|
92
|
+
|
|
93
|
+
The unit test suite can be run on both node.js and Chrome to ensure behaviour is consistent between the two environments.
|
|
94
|
+
|
|
95
|
+
[Mocha](https://www.npmjs.com/package/mocha) is used as a test runner in both environments, in the browser it is run via [playwright-test](https://www.npmjs.com/package/playwright-test).
|
|
96
|
+
|
|
97
|
+
#### Running all tests:
|
|
98
|
+
|
|
99
|
+
```console
|
|
100
|
+
$ npm test
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
#### Running in node
|
|
104
|
+
|
|
105
|
+
```console
|
|
106
|
+
$ npm run test:node
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
#### Running in Chromium
|
|
110
|
+
|
|
111
|
+
```console
|
|
112
|
+
$ npm run test:chrome
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### Forward args
|
|
116
|
+
|
|
117
|
+
Forward args are supported so you can pass any Mocha or playwright-test options after the `--`:
|
|
118
|
+
|
|
119
|
+
E.g.:
|
|
120
|
+
|
|
121
|
+
Run only "unidirectional streams" tests:
|
|
122
|
+
|
|
123
|
+
```console
|
|
124
|
+
$ npm run test:node -- --grep '"unidirectional streams"'
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Disable headless mode to watch tests run in Chromium:
|
|
128
|
+
|
|
129
|
+
```console
|
|
130
|
+
$ npm run test:chromium -- --debug
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Logging
|
|
134
|
+
|
|
135
|
+
This module uses the [debug](https://www.npmjs.com/package/debug) module for logging.
|
|
136
|
+
|
|
137
|
+
To enable logging, specify the `DEBUG` environmental variable:
|
|
138
|
+
|
|
139
|
+
```console
|
|
140
|
+
$ DEBUG=webtransport* node my-script.js
|
|
141
|
+
// debug output
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
#### Trace logging
|
|
145
|
+
|
|
146
|
+
To enable detailed output, additionally set the `DEBUG_TRACE` environmental variable:
|
|
147
|
+
|
|
148
|
+
```console
|
|
149
|
+
$ DEBUG=webtransport* DEBUG_TRACE=true node my-script.js
|
|
150
|
+
// lots of debug output
|
|
151
|
+
```
|
package/src/http3client.cc
CHANGED
|
@@ -1329,9 +1329,9 @@ namespace quic
|
|
|
1329
1329
|
return;
|
|
1330
1330
|
}
|
|
1331
1331
|
|
|
1332
|
-
if (lobj.Has("
|
|
1332
|
+
if (lobj.Has("host") && !(lobj).Get("host").IsEmpty())
|
|
1333
1333
|
{
|
|
1334
|
-
Napi::Value hostnameValue = (lobj).Get("
|
|
1334
|
+
Napi::Value hostnameValue = (lobj).Get("host");
|
|
1335
1335
|
hostname = hostnameValue.ToString().Utf8Value();
|
|
1336
1336
|
}
|
|
1337
1337
|
else
|
package/src/http3dispatcher.cc
CHANGED
|
@@ -43,13 +43,14 @@ std::unique_ptr<QuicSession> Http3Dispatcher::CreateQuicSession(
|
|
|
43
43
|
QuicConnectionId connection_id, const QuicSocketAddress& self_address,
|
|
44
44
|
const QuicSocketAddress& peer_address, absl::string_view /*alpn*/,
|
|
45
45
|
const ParsedQuicVersion& version,
|
|
46
|
-
const ParsedClientHello& /*parsed_chlo
|
|
46
|
+
const ParsedClientHello& /*parsed_chlo*/,
|
|
47
|
+
ConnectionIdGeneratorInterface& connection_id_generator) {
|
|
47
48
|
// The QuicServerSessionBase takes ownership of |connection| below.
|
|
48
49
|
QuicConnection* connection =
|
|
49
50
|
new QuicConnection(connection_id, self_address, peer_address, helper(),
|
|
50
51
|
alarm_factory(), writer(),
|
|
51
52
|
/* owns_writer= */ false, Perspective::IS_SERVER,
|
|
52
|
-
ParsedQuicVersionVector{version}, connection_id_generator
|
|
53
|
+
ParsedQuicVersionVector{version}, connection_id_generator);
|
|
53
54
|
|
|
54
55
|
auto session = std::make_unique<Http3ServerSession>(
|
|
55
56
|
config(), GetSupportedVersions(), connection, this, session_helper(),
|
package/src/http3dispatcher.h
CHANGED
|
@@ -40,7 +40,8 @@ namespace quic
|
|
|
40
40
|
QuicConnectionId connection_id, const QuicSocketAddress &self_address,
|
|
41
41
|
const QuicSocketAddress &peer_address, absl::string_view alpn,
|
|
42
42
|
const ParsedQuicVersion &version,
|
|
43
|
-
const ParsedClientHello &parsed_chlo
|
|
43
|
+
const ParsedClientHello &parsed_chlo,
|
|
44
|
+
ConnectionIdGeneratorInterface& connection_id_generator) override;
|
|
44
45
|
|
|
45
46
|
Http3ServerBackend *server_backend()
|
|
46
47
|
{
|
package/src/http3eventloop.cc
CHANGED
|
@@ -33,6 +33,7 @@ namespace quic
|
|
|
33
33
|
static const int kErrorBufferSize = 256;
|
|
34
34
|
|
|
35
35
|
const size_t kNumSessionsToCreatePerSocketEvent = 16;
|
|
36
|
+
bool Http3EventLoop::hasSetLogging = false;
|
|
36
37
|
|
|
37
38
|
Http3EventLoop::~Http3EventLoop()
|
|
38
39
|
{
|
|
@@ -220,6 +221,31 @@ namespace quic
|
|
|
220
221
|
progress_->Send(&report, 1);
|
|
221
222
|
}
|
|
222
223
|
|
|
224
|
+
void Http3EventLoop::informSessionStats(Http3WTSession *sessionobj, webtransport::SessionStats * sessstats)
|
|
225
|
+
{
|
|
226
|
+
Http3ProgressReport report;
|
|
227
|
+
report.type = Http3ProgressReport::SessionStats;
|
|
228
|
+
report.sessionobj = sessionobj;
|
|
229
|
+
report.sessionStats = sessstats;
|
|
230
|
+
|
|
231
|
+
report.timestamp = new absl::Duration();
|
|
232
|
+
report.timestamp[0] = absl::Now() - absl::UnixEpoch();
|
|
233
|
+
if (progress_)
|
|
234
|
+
progress_->Send(&report, 1);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
void Http3EventLoop::informDatagramStats(Http3WTSession *sessionobj, webtransport::DatagramStats * datastats)
|
|
238
|
+
{
|
|
239
|
+
Http3ProgressReport report;
|
|
240
|
+
report.type = Http3ProgressReport::DatagramStats;
|
|
241
|
+
report.sessionobj = sessionobj;
|
|
242
|
+
report.datagramStats = datastats;
|
|
243
|
+
report.timestamp = new absl::Duration();
|
|
244
|
+
report.timestamp[0] = absl::Now() - absl::UnixEpoch();
|
|
245
|
+
if (progress_)
|
|
246
|
+
progress_->Send(&report, 1);
|
|
247
|
+
}
|
|
248
|
+
|
|
223
249
|
void Http3EventLoop::informUnref(LifetimeHelper *obj)
|
|
224
250
|
{
|
|
225
251
|
Http3ProgressReport report;
|
|
@@ -591,6 +617,70 @@ namespace quic
|
|
|
591
617
|
cbsession_.Call({retObj});
|
|
592
618
|
}
|
|
593
619
|
|
|
620
|
+
void Http3EventLoop::processSessionStats(Http3WTSession *sessionobj, absl::Duration* timestamp, webtransport::SessionStats * sessstats)
|
|
621
|
+
{
|
|
622
|
+
if (!checkQw())
|
|
623
|
+
return;
|
|
624
|
+
HandleScope scope(qw_->Env());
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
auto session = sessionobj->getJS();
|
|
628
|
+
if (!session)
|
|
629
|
+
return;
|
|
630
|
+
Napi::Object objVal = session->Value();
|
|
631
|
+
|
|
632
|
+
Napi::Object retObj = Napi::Object::New(qw_->Env());
|
|
633
|
+
retObj.Set("purpose", "SessionStats");
|
|
634
|
+
retObj.Set("object", objVal);
|
|
635
|
+
// expiredOutgoing: bigint
|
|
636
|
+
// lostOutgoing: bigint
|
|
637
|
+
|
|
638
|
+
// non Datagram
|
|
639
|
+
// minRtt: number
|
|
640
|
+
// smoothedRtt: number
|
|
641
|
+
// rttVariation: number
|
|
642
|
+
// estimatedSendRateBps: bigint
|
|
643
|
+
retObj.Set("timestamp", absl::ToDoubleMilliseconds(*timestamp)); // absl::Duration
|
|
644
|
+
// datagram
|
|
645
|
+
retObj.Set("expiredOutgoing", Napi::BigInt::New(qw_->Env(), sessstats->datagram_stats.expired_outgoing)); //uint64_t
|
|
646
|
+
retObj.Set("lostOutgoing", Napi::BigInt::New(qw_->Env(), sessstats->datagram_stats.lost_outgoing)); //uint64_t
|
|
647
|
+
|
|
648
|
+
// non Datagram
|
|
649
|
+
retObj.Set("minRtt", absl::ToDoubleMilliseconds(sessstats->min_rtt)); // absl::Duration
|
|
650
|
+
retObj.Set("smoothedRtt", absl::ToDoubleMilliseconds(sessstats->smoothed_rtt)); // absl::Duration
|
|
651
|
+
retObj.Set("rttVariation", absl::ToDoubleMilliseconds(sessstats->rtt_variation)); // absl::Duration
|
|
652
|
+
retObj.Set("estimatedSendRateBps", sessstats->estimated_send_rate_bps); // absl::Duration
|
|
653
|
+
|
|
654
|
+
cbsession_.Call({retObj});
|
|
655
|
+
delete sessstats;
|
|
656
|
+
delete timestamp;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
void Http3EventLoop::processDatagramStats(Http3WTSession *sessionobj, absl::Duration* timestamp, webtransport::DatagramStats * datastats)
|
|
660
|
+
{
|
|
661
|
+
if (!checkQw())
|
|
662
|
+
return;
|
|
663
|
+
HandleScope scope(qw_->Env());
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
auto session = sessionobj->getJS();
|
|
667
|
+
if (!session)
|
|
668
|
+
return;
|
|
669
|
+
Napi::Object objVal = session->Value();
|
|
670
|
+
|
|
671
|
+
Napi::Object retObj = Napi::Object::New(qw_->Env());
|
|
672
|
+
retObj.Set("purpose", "DatagramStats");
|
|
673
|
+
retObj.Set("object", objVal);
|
|
674
|
+
retObj.Set("timestamp", absl::ToDoubleMilliseconds(*timestamp)); // absl::Duration
|
|
675
|
+
// datagram
|
|
676
|
+
retObj.Set("expiredOutgoing", Napi::BigInt::New(qw_->Env(), datastats->expired_outgoing)); //uint64_t
|
|
677
|
+
retObj.Set("lostOutgoing", Napi::BigInt::New(qw_->Env(), datastats->lost_outgoing)); //uint64_t
|
|
678
|
+
|
|
679
|
+
cbsession_.Call({retObj});
|
|
680
|
+
delete datastats;
|
|
681
|
+
delete timestamp;
|
|
682
|
+
}
|
|
683
|
+
|
|
594
684
|
void Http3EventLoop::processNewSessionRequest(Http3Server *serverobj, WebTransportSession *session, spdy::Http2HeaderBlock *reqheadcopy, WebTransportRespPromisePtr *promise)
|
|
595
685
|
{
|
|
596
686
|
if (!checkQw())
|
|
@@ -883,6 +973,18 @@ namespace quic
|
|
|
883
973
|
processGoawayReceived(cur.sessionobj);
|
|
884
974
|
}
|
|
885
975
|
break;
|
|
976
|
+
case Http3ProgressReport::SessionStats:
|
|
977
|
+
{
|
|
978
|
+
processSessionStats(cur.sessionobj, cur.timestamp, cur.sessionStats);
|
|
979
|
+
cur.para = nullptr; // take ownership of the data
|
|
980
|
+
}
|
|
981
|
+
break;
|
|
982
|
+
case Http3ProgressReport::DatagramStats:
|
|
983
|
+
{
|
|
984
|
+
processDatagramStats(cur.sessionobj, cur.timestamp, cur.datagramStats);
|
|
985
|
+
cur.para = nullptr; // take ownership of the data
|
|
986
|
+
}
|
|
987
|
+
break;
|
|
886
988
|
case Http3ProgressReport::Unref:
|
|
887
989
|
{
|
|
888
990
|
cur.obj->doUnref();
|
|
@@ -969,8 +1071,10 @@ namespace quic
|
|
|
969
1071
|
for (auto cur= quiche_cmd_line.begin(); cur != quiche_cmd_line.end(); cur++) {
|
|
970
1072
|
quiche_cmd_line_char.push_back((*cur).c_str());
|
|
971
1073
|
}
|
|
972
|
-
|
|
973
|
-
|
|
1074
|
+
if (!hasSetLogging) {
|
|
1075
|
+
quiche::QuicheParseCommandLineFlags("No use instruction.", quiche_cmd_line.size(), &(*quiche_cmd_line_char.begin()));
|
|
1076
|
+
hasSetLogging = true;
|
|
1077
|
+
}
|
|
974
1078
|
}
|
|
975
1079
|
|
|
976
1080
|
void Http3EventLoop::startEventLoop(const Napi::CallbackInfo &info)
|
package/src/http3eventloop.h
CHANGED
|
@@ -94,6 +94,8 @@ namespace quic
|
|
|
94
94
|
DatagramReceived,
|
|
95
95
|
DatagramSend,
|
|
96
96
|
GoawayReceived,
|
|
97
|
+
SessionStats,
|
|
98
|
+
DatagramStats,
|
|
97
99
|
Unref
|
|
98
100
|
} type;
|
|
99
101
|
union
|
|
@@ -125,12 +127,15 @@ namespace quic
|
|
|
125
127
|
{
|
|
126
128
|
std::string *para = nullptr; // for session and others, we own it, and must delete it
|
|
127
129
|
ServerStatusDetails *details;
|
|
130
|
+
webtransport::SessionStats * sessionStats; // we own it and must delete it after return from js
|
|
131
|
+
webtransport::DatagramStats * datagramStats; // we own it and must delete it after return from js
|
|
128
132
|
};
|
|
129
133
|
union
|
|
130
134
|
{
|
|
131
135
|
bool success;
|
|
132
136
|
WebTransportRespPromisePtr *promise;
|
|
133
137
|
Napi::Reference<Napi::Value> *header;
|
|
138
|
+
absl::Duration *timestamp; // for session and others, we own it, and must delete it
|
|
134
139
|
};
|
|
135
140
|
};
|
|
136
141
|
|
|
@@ -219,6 +224,9 @@ namespace quic
|
|
|
219
224
|
void informDatagramReceived(Http3WTSession *sessionobj, absl::string_view datagram);
|
|
220
225
|
void informDatagramSend(Http3WTSession *sessionobj, Napi::ObjectReference *bufferhandle);
|
|
221
226
|
|
|
227
|
+
void informSessionStats(Http3WTSession *sessionobj, webtransport::SessionStats * sessstats);
|
|
228
|
+
void informDatagramStats(Http3WTSession *sessionobj, webtransport::DatagramStats * datastats);
|
|
229
|
+
|
|
222
230
|
void informGoawayReceived(Http3WTSession *sessionobj);
|
|
223
231
|
|
|
224
232
|
void informUnref(LifetimeHelper *obj);
|
|
@@ -256,6 +264,8 @@ namespace quic
|
|
|
256
264
|
return my_constructor;
|
|
257
265
|
}
|
|
258
266
|
|
|
267
|
+
static bool hasSetLogging;
|
|
268
|
+
|
|
259
269
|
void ExecuteScheduledActions();
|
|
260
270
|
|
|
261
271
|
QuicMutex scheduled_actions_lock_;
|
|
@@ -286,6 +296,9 @@ namespace quic
|
|
|
286
296
|
void processDatagramReceived(Http3WTSession *sessionobj, std::string *datagram);
|
|
287
297
|
void processDatagramSend(Http3WTSession *sessionobj, Napi::ObjectReference *bufferhandle);
|
|
288
298
|
|
|
299
|
+
void processSessionStats(Http3WTSession *sessionobj, absl::Duration* timestamp, webtransport::SessionStats * sessstats);
|
|
300
|
+
void processDatagramStats(Http3WTSession *sessionobj, absl::Duration* timestamp, webtransport::DatagramStats * datastats);
|
|
301
|
+
|
|
289
302
|
void processGoawayReceived(Http3WTSession *sessionobj);
|
|
290
303
|
|
|
291
304
|
bool shutDownEventLoopInt();
|
|
@@ -10,6 +10,7 @@ namespace quic
|
|
|
10
10
|
|
|
11
11
|
Http3WTSession::Visitor::~Visitor()
|
|
12
12
|
{
|
|
13
|
+
// printf("~Visitor %d %x %x\n", getpid(), this, session_);
|
|
13
14
|
Http3WTSessionJS *sessobj = session_->getJS();
|
|
14
15
|
if (sessobj)
|
|
15
16
|
session_->eventloop_->informUnref(sessobj);
|
|
@@ -21,6 +22,7 @@ namespace quic
|
|
|
21
22
|
void Http3WTSession::Visitor::OnSessionClosed(WebTransportSessionError error_code,
|
|
22
23
|
const std::string &error_message)
|
|
23
24
|
{
|
|
25
|
+
// printf("OnSessionClosed %d %x %x\n", getpid(), this, session_);
|
|
24
26
|
session_->session_ = nullptr;
|
|
25
27
|
session_->eventloop_->informSessionClosed(session_, error_code, error_message);
|
|
26
28
|
}
|
|
@@ -118,6 +118,7 @@ namespace quic
|
|
|
118
118
|
|
|
119
119
|
void OnDatagramReceived(absl::string_view datagram) override
|
|
120
120
|
{
|
|
121
|
+
// printf("OnDatagramReceived %d %x %x\n", getpid(), this, session_);
|
|
121
122
|
session_->eventloop_->informDatagramReceived(session_, datagram);
|
|
122
123
|
/*auto buffer = MakeUniqueBuffer(&allocator_, datagram.size());
|
|
123
124
|
memcpy(buffer.get(), datagram.data(), datagram.size());
|
|
@@ -230,6 +231,28 @@ namespace quic
|
|
|
230
231
|
eventloop_->Schedule(task);
|
|
231
232
|
}
|
|
232
233
|
|
|
234
|
+
void orderSessionStatsInt()
|
|
235
|
+
{
|
|
236
|
+
std::function<void()> task = [this](){
|
|
237
|
+
if (session_) {
|
|
238
|
+
webtransport::SessionStats * stats = new webtransport::SessionStats();
|
|
239
|
+
*stats = session_->GetSessionStats();
|
|
240
|
+
eventloop_->informSessionStats(this, stats);
|
|
241
|
+
}};
|
|
242
|
+
eventloop_->Schedule(task);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
void orderDatagramStatsInt()
|
|
246
|
+
{
|
|
247
|
+
std::function<void()> task = [this]()
|
|
248
|
+
{ if (session_) {
|
|
249
|
+
webtransport::DatagramStats * stats = new webtransport::DatagramStats();
|
|
250
|
+
*stats = session_->GetDatagramStats();
|
|
251
|
+
eventloop_->informDatagramStats(this, stats);
|
|
252
|
+
} };
|
|
253
|
+
eventloop_->Schedule(task);
|
|
254
|
+
}
|
|
255
|
+
|
|
233
256
|
void closeInt(int code, std::string &reason)
|
|
234
257
|
{
|
|
235
258
|
std::function<void()> task = [this, code, reason]()
|
|
@@ -239,12 +262,15 @@ namespace quic
|
|
|
239
262
|
|
|
240
263
|
void writeDatagramInt(char *buffer, size_t len, Napi::ObjectReference *bufferhandle)
|
|
241
264
|
{
|
|
265
|
+
// printf("Datagram write %d %x %x\n", getpid(), this, session_ );
|
|
242
266
|
if (!session_)
|
|
243
267
|
{
|
|
268
|
+
// printf("Datagram session gone %d %x %x\n", getpid(), this, session_);
|
|
244
269
|
eventloop_->informDatagramSend(this, bufferhandle);
|
|
245
270
|
return;
|
|
246
271
|
}
|
|
247
|
-
session_->SendOrQueueDatagram(absl::string_view(buffer, len));
|
|
272
|
+
auto status=session_->SendOrQueueDatagram(absl::string_view(buffer, len));
|
|
273
|
+
// printf("Datagram status %d %d %s %x %x\n", getpid(), status.code, status.error_message.c_str(), this, session_);
|
|
248
274
|
eventloop_->informDatagramSend(this, bufferhandle);
|
|
249
275
|
}
|
|
250
276
|
|
|
@@ -300,6 +326,16 @@ namespace quic
|
|
|
300
326
|
wtsession_->notifySessionDrainingInt();
|
|
301
327
|
}
|
|
302
328
|
|
|
329
|
+
void orderSessionStats(const Napi::CallbackInfo &info)
|
|
330
|
+
{
|
|
331
|
+
wtsession_->orderSessionStatsInt();
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
void orderDatagramStats(const Napi::CallbackInfo &info)
|
|
335
|
+
{
|
|
336
|
+
wtsession_->orderDatagramStatsInt();
|
|
337
|
+
}
|
|
338
|
+
|
|
303
339
|
void close(const Napi::CallbackInfo &info)
|
|
304
340
|
{
|
|
305
341
|
int code = 0;
|
|
@@ -338,6 +374,10 @@ namespace quic
|
|
|
338
374
|
static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
|
|
339
375
|
InstanceMethod<&Http3WTSessionJS::notifySessionDraining>("notifySessionDraining",
|
|
340
376
|
static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
|
|
377
|
+
InstanceMethod<&Http3WTSessionJS::orderSessionStats>("orderSessionStats",
|
|
378
|
+
static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
|
|
379
|
+
InstanceMethod<&Http3WTSessionJS::orderDatagramStats>("orderDatagramStats",
|
|
380
|
+
static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
|
|
341
381
|
InstanceMethod<&Http3WTSessionJS::close>("close",
|
|
342
382
|
static_cast<napi_property_attributes>(napi_writable | napi_configurable))});
|
|
343
383
|
constr->session = Napi::Persistent(tplwt);
|