uwebsockets 2.2.1 → 3.0.0
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/.github/workflows/c-cpp.yml +11 -11
- package/ESM_wrapper.mjs +53 -0
- package/README.md +5 -5
- package/docs/generated/enums/ListenOptions.html +6 -6
- package/docs/generated/functions/App.html +4 -4
- package/docs/generated/functions/SSLApp.html +4 -4
- package/docs/generated/functions/getParts.html +4 -4
- package/docs/generated/functions/us_listen_socket_close.html +4 -4
- package/docs/generated/functions/us_socket_local_port.html +4 -4
- package/docs/generated/index.html +3 -3
- package/docs/generated/interfaces/AppOptions.html +11 -11
- package/docs/generated/interfaces/HttpRequest.html +13 -13
- package/docs/generated/interfaces/HttpResponse.html +22 -22
- package/docs/generated/interfaces/MultipartField.html +8 -8
- package/docs/generated/interfaces/TemplatedApp.html +23 -23
- package/docs/generated/interfaces/WebSocket.html +18 -18
- package/docs/generated/interfaces/WebSocketBehavior.html +19 -19
- package/docs/generated/interfaces/us_listen_socket.html +4 -4
- package/docs/generated/interfaces/us_socket.html +4 -4
- package/docs/generated/interfaces/us_socket_context_t.html +4 -4
- package/docs/generated/types/CompressOptions.html +4 -4
- package/docs/generated/types/RecognizedString.html +4 -4
- package/docs/generated/variables/DEDICATED_COMPRESSOR_128KB.html +4 -4
- package/docs/generated/variables/DEDICATED_COMPRESSOR_16KB.html +4 -4
- package/docs/generated/variables/DEDICATED_COMPRESSOR_256KB.html +4 -4
- package/docs/generated/variables/DEDICATED_COMPRESSOR_32KB.html +4 -4
- package/docs/generated/variables/DEDICATED_COMPRESSOR_3KB.html +4 -4
- package/docs/generated/variables/DEDICATED_COMPRESSOR_4KB.html +4 -4
- package/docs/generated/variables/DEDICATED_COMPRESSOR_64KB.html +4 -4
- package/docs/generated/variables/DEDICATED_COMPRESSOR_8KB.html +4 -4
- package/docs/generated/variables/DEDICATED_DECOMPRESSOR.html +4 -4
- package/docs/generated/variables/DEDICATED_DECOMPRESSOR_16KB.html +4 -4
- package/docs/generated/variables/DEDICATED_DECOMPRESSOR_1KB.html +4 -4
- package/docs/generated/variables/DEDICATED_DECOMPRESSOR_2KB.html +4 -4
- package/docs/generated/variables/DEDICATED_DECOMPRESSOR_32KB.html +4 -4
- package/docs/generated/variables/DEDICATED_DECOMPRESSOR_4KB.html +4 -4
- package/docs/generated/variables/DEDICATED_DECOMPRESSOR_512B.html +4 -4
- package/docs/generated/variables/DEDICATED_DECOMPRESSOR_8KB.html +4 -4
- package/docs/generated/variables/DISABLED.html +4 -4
- package/docs/generated/variables/SHARED_COMPRESSOR.html +4 -4
- package/docs/generated/variables/SHARED_DECOMPRESSOR.html +4 -4
- package/docs/tsconfig.json +9 -9
- package/examples/SlowReceiver.js +41 -38
- package/index.d.ts +106 -69
- package/logo.svg +1 -0
- package/package.json +2 -2
- package/source_commit +1 -1
- package/tests/Hammer.js +152 -149
- package/tests/fuzzingclient.json +26 -26
- package/uws.js +2 -2
- package/uws_darwin_arm64_108.node +0 -0
- package/uws_darwin_arm64_115.node +0 -0
- package/uws_darwin_arm64_120.node +0 -0
- package/uws_darwin_arm64_93.node +0 -0
- package/uws_darwin_x64_108.node +0 -0
- package/uws_darwin_x64_115.node +0 -0
- package/uws_darwin_x64_120.node +0 -0
- package/uws_darwin_x64_93.node +0 -0
- package/uws_linux_arm64_108.node +0 -0
- package/uws_linux_arm64_115.node +0 -0
- package/uws_linux_arm64_120.node +0 -0
- package/uws_linux_arm64_93.node +0 -0
- package/uws_linux_arm_108.node +0 -0
- package/uws_linux_arm_115.node +0 -0
- package/uws_linux_arm_120.node +0 -0
- package/uws_linux_arm_93.node +0 -0
- package/uws_linux_x64_108.node +0 -0
- package/uws_linux_x64_115.node +0 -0
- package/uws_linux_x64_120.node +0 -0
- package/uws_linux_x64_93.node +0 -0
- package/uws_win32_x64_108.node +0 -0
- package/uws_win32_x64_115.node +0 -0
- package/uws_win32_x64_120.node +0 -0
- package/uws_win32_x64_93.node +0 -0
package/tests/Hammer.js
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
/* Run with AddressSanitizer enabled for best effect. */
|
|
8
8
|
|
|
9
9
|
/* We use websockets/ws as client counterpart */
|
|
10
|
-
const WebSocket = require(
|
|
10
|
+
const WebSocket = require("ws");
|
|
11
11
|
|
|
12
|
-
const uWS = require(
|
|
12
|
+
const uWS = require("../dist/uws.js");
|
|
13
13
|
const port = 9001;
|
|
14
14
|
|
|
15
15
|
let openedClientConnections = 0;
|
|
@@ -22,182 +22,185 @@ const maxPayloadSize = 5 * 1024 * 1024;
|
|
|
22
22
|
const largeBuffer = new ArrayBuffer(maxPayloadSize);
|
|
23
23
|
|
|
24
24
|
function printStatistics() {
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
console.log("Opened clients " + openedClientConnections);
|
|
26
|
+
console.log("Closed clients " + closedClientConnections + "\n");
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/* 0 to 1-less than max */
|
|
30
30
|
function getRandomInt(max) {
|
|
31
|
-
|
|
31
|
+
return Math.floor(Math.random() * Math.floor(max));
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
/* This gets called every time we either open a new connection,
|
|
35
35
|
* or it immediately land in websockets/ws error handler */
|
|
36
36
|
function accountForConnection() {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
/* Open more connections */
|
|
38
|
+
if (++openedClientConnections < /*100*/ 1000) {
|
|
39
|
+
establishNewConnection();
|
|
40
|
+
} else {
|
|
41
|
+
/* Stop listening */
|
|
42
|
+
uWS.us_listen_socket_close(listenSocket);
|
|
43
|
+
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
function establishNewConnection() {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
47
|
+
const ws = new WebSocket("ws://localhost:" + port);
|
|
48
|
+
|
|
49
|
+
ws.on("open", () => {
|
|
50
|
+
/* Mark this socket as opened */
|
|
51
|
+
ws._opened = true;
|
|
52
|
+
accountForConnection();
|
|
53
|
+
|
|
54
|
+
printStatistics();
|
|
55
|
+
performRandomClientAction(ws);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
/* It seems you can get messages after close?! */
|
|
59
|
+
ws.on("message", (data) => {
|
|
60
|
+
performRandomClientAction(ws);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
/* Close can be called more times than open, websockets/ws is really messy! */
|
|
64
|
+
ws.on("close", () => {
|
|
65
|
+
/* Check if this websocket really was opened first */
|
|
66
|
+
if (!ws._opened) {
|
|
67
|
+
accountForConnection();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
closedClientConnections++;
|
|
71
|
+
printStatistics();
|
|
72
|
+
/* I guess there is no need for us to call anything
|
|
73
|
+
* here, websockets/ws will not send anything to us anyways */
|
|
74
|
+
//performRandomClientAction(ws);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
ws.on("error", () => {
|
|
78
|
+
/* We simply ignore errors. websockets/ws will call our close handler
|
|
79
|
+
* on errors, potentially before even calling the open handler */
|
|
80
|
+
});
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
/* Perform random websockets/ws action */
|
|
84
84
|
function performRandomClientAction(ws) {
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
/* 0, 1, 2 but never 3 */
|
|
86
|
+
let action = getRandomInt(3);
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
88
|
+
/* Sending a message should have higher probability */
|
|
89
|
+
if (getRandomInt(100) < 80) {
|
|
90
|
+
action = 1;
|
|
91
|
+
}
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
|
-
case 2: {
|
|
109
|
-
ws.terminate();
|
|
110
|
-
break;
|
|
111
|
-
}
|
|
93
|
+
switch (action) {
|
|
94
|
+
case 0: {
|
|
95
|
+
ws.close();
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
case 1: {
|
|
99
|
+
/* Length should be random from small to huge */
|
|
100
|
+
try {
|
|
101
|
+
ws.send("a test message");
|
|
102
|
+
} catch (e) {
|
|
103
|
+
/* Apparently websockets/ws can throw at any moment */
|
|
104
|
+
}
|
|
105
|
+
break;
|
|
112
106
|
}
|
|
107
|
+
case 2: {
|
|
108
|
+
ws.terminate();
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
113
112
|
}
|
|
114
113
|
|
|
115
|
-
/* Perform random
|
|
114
|
+
/* Perform random uwebsockets action */
|
|
116
115
|
function performRandomServerAction(ws, uniform) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
116
|
+
/* 0, 1, 2 but never 3 */
|
|
117
|
+
let action = getRandomInt(3);
|
|
118
|
+
|
|
119
|
+
/* Sending a message should have higher probability,
|
|
120
|
+
* except for when we are draining. */
|
|
121
|
+
if (!uniform) {
|
|
122
|
+
if (getRandomInt(100) < 80) {
|
|
123
|
+
action = 1;
|
|
126
124
|
}
|
|
125
|
+
}
|
|
127
126
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
case 2: {
|
|
145
|
-
ws.close();
|
|
146
|
-
break;
|
|
147
|
-
}
|
|
127
|
+
switch (action) {
|
|
128
|
+
case 0: {
|
|
129
|
+
ws.end();
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
case 1: {
|
|
133
|
+
/* If we have very high backpressure we skip sending more */
|
|
134
|
+
if (ws.getBufferedAmount() > maxBackpressure) {
|
|
135
|
+
/* Do something else instead */
|
|
136
|
+
performRandomServerAction(ws);
|
|
137
|
+
} else {
|
|
138
|
+
/* Length should be random from small to huge, ArrayBuffer.slice is a copy (bad but we don't care I guess) */
|
|
139
|
+
ws.send(largeBuffer.slice(0, getRandomInt(maxPayloadSize + 1)));
|
|
140
|
+
}
|
|
141
|
+
break;
|
|
148
142
|
}
|
|
143
|
+
case 2: {
|
|
144
|
+
ws.close();
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
149
148
|
}
|
|
150
149
|
|
|
151
|
-
const app = uWS
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
/*
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
150
|
+
const app = uWS
|
|
151
|
+
./*SSL*/ App({
|
|
152
|
+
key_file_name: "misc/key.pem",
|
|
153
|
+
cert_file_name: "misc/cert.pem",
|
|
154
|
+
passphrase: "1234",
|
|
155
|
+
})
|
|
156
|
+
.ws("/*", {
|
|
157
|
+
compression: 0,
|
|
158
|
+
/* We intentionally accept less than what might be sent so to test force closing */
|
|
159
|
+
maxPayloadLength: maxPayloadSize / 2,
|
|
160
|
+
idleTimeout: 100,
|
|
161
|
+
|
|
162
|
+
open: (ws, req) => {
|
|
163
|
+
/* Doing a terminate here will be interesting */
|
|
164
|
+
performRandomServerAction(ws, false);
|
|
165
|
+
},
|
|
166
|
+
message: (ws, message, isBinary) => {
|
|
167
|
+
performRandomServerAction(ws, false);
|
|
168
|
+
},
|
|
169
|
+
drain: (ws) => {
|
|
170
|
+
/* We only perform actions while draining rarely (5%), and we do it uniformly.
|
|
171
|
+
* There's no real NEED to do anything here, as it will eventually result in
|
|
172
|
+
* message event for client. */
|
|
173
|
+
if (getRandomInt(100) < 5) {
|
|
173
174
|
performRandomServerAction(ws, true);
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
close: (ws, code, message) => {
|
|
178
|
+
/* TODO: We SHOULD TECHNICALLY allow sending here.
|
|
179
|
+
* It should not throw, but just silently ignore it
|
|
180
|
+
* as it makes no sense to send on a closed socket
|
|
181
|
+
* while still being technically valid */
|
|
182
|
+
try {
|
|
182
183
|
performRandomServerAction(ws, false);
|
|
183
|
-
|
|
184
|
+
} catch (e) {
|
|
184
185
|
/* We expect to land here always, since socket is invalid */
|
|
185
186
|
return;
|
|
187
|
+
}
|
|
188
|
+
/* We should never land here */
|
|
189
|
+
uWS.print("ERROR: Did not throw in close!");
|
|
190
|
+
process.exit(-1);
|
|
191
|
+
},
|
|
192
|
+
})
|
|
193
|
+
.any("/*", (res, req) => {
|
|
194
|
+
res.end("Nothing to see here!");
|
|
195
|
+
})
|
|
196
|
+
.listen(port, (token) => {
|
|
197
|
+
if (token) {
|
|
198
|
+
console.log("Hammering on port " + port);
|
|
199
|
+
|
|
200
|
+
/* Establish first connection */
|
|
201
|
+
establishNewConnection();
|
|
202
|
+
|
|
203
|
+
/* Use this to stop listening when done */
|
|
204
|
+
listenSocket = token;
|
|
186
205
|
}
|
|
187
|
-
|
|
188
|
-
uWS.print('ERROR: Did not throw in close!');
|
|
189
|
-
process.exit(-1);
|
|
190
|
-
}
|
|
191
|
-
}).any('/*', (res, req) => {
|
|
192
|
-
res.end('Nothing to see here!');
|
|
193
|
-
}).listen(port, (token) => {
|
|
194
|
-
if (token) {
|
|
195
|
-
console.log('Hammering on port ' + port);
|
|
196
|
-
|
|
197
|
-
/* Establish first connection */
|
|
198
|
-
establishNewConnection();
|
|
199
|
-
|
|
200
|
-
/* Use this to stop listening when done */
|
|
201
|
-
listenSocket = token;
|
|
202
|
-
}
|
|
203
|
-
});
|
|
206
|
+
});
|
package/tests/fuzzingclient.json
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
2
|
+
"outdir": "./reports/servers",
|
|
3
|
+
"servers": [
|
|
4
|
+
{
|
|
5
|
+
"url": "ws://localhost:9001",
|
|
6
|
+
"agent": "uwebsockets non-SSL, non-compression"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"url": "wss://localhost:9002",
|
|
10
|
+
"agent": "uwebsockets SSL, shared compressor"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"url": "ws://localhost:9003",
|
|
14
|
+
"agent": "uwebsockets non-SSL, dedicated compressor"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"url": "ws://localhost:9004",
|
|
18
|
+
"agent": "uwebsockets non-SSL, non-compression, pubsub based"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"url": "wss://localhost:9005",
|
|
22
|
+
"agent": "uwebsockets SSL, non-compression, pubsub based"
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"cases": ["*.*"],
|
|
26
|
+
"exclude-cases": [],
|
|
27
|
+
"exclude-agent-cases": {}
|
|
28
28
|
}
|
package/uws.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Authored by Alex Hultman, 2018-
|
|
2
|
+
* Authored by Alex Hultman, 2018-2022.
|
|
3
3
|
* Intellectual property of third-party.
|
|
4
4
|
|
|
5
5
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -19,6 +19,6 @@ module.exports = (() => {
|
|
|
19
19
|
try {
|
|
20
20
|
return require('./uws_' + process.platform + '_' + process.arch + '_' + process.versions.modules + '.node');
|
|
21
21
|
} catch (e) {
|
|
22
|
-
throw new Error('This version of
|
|
22
|
+
throw new Error('This version of uWS.js supports only Node.js LTS versions 16, 18 and 20 on (glibc) Linux, macOS and Windows, on Tier 1 platforms (https://github.com/nodejs/node/blob/master/BUILDING.md#platform-list).\n\n' + e.toString());
|
|
23
23
|
}
|
|
24
24
|
})();
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/uws_darwin_arm64_93.node
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/uws_darwin_x64_93.node
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/uws_linux_arm64_93.node
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/uws_linux_x64_93.node
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/uws_win32_x64_93.node
CHANGED
|
Binary file
|