@gleamkit/engine.io 6.6.3
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/LICENSE +19 -0
- package/README.md +603 -0
- package/build/engine.io.d.ts +26 -0
- package/build/engine.io.js +54 -0
- package/build/parser-v3/index.d.ts +94 -0
- package/build/parser-v3/index.js +424 -0
- package/build/parser-v3/utf8.d.ts +14 -0
- package/build/parser-v3/utf8.js +187 -0
- package/build/server.d.ts +267 -0
- package/build/server.js +786 -0
- package/build/socket.d.ts +180 -0
- package/build/socket.js +460 -0
- package/build/transport.d.ts +124 -0
- package/build/transport.js +117 -0
- package/build/transports/index.d.ts +16 -0
- package/build/transports/index.js +23 -0
- package/build/transports/polling-jsonp.d.ts +12 -0
- package/build/transports/polling-jsonp.js +41 -0
- package/build/transports/polling.d.ts +87 -0
- package/build/transports/polling.js +332 -0
- package/build/transports/websocket.d.ts +32 -0
- package/build/transports/websocket.js +94 -0
- package/build/transports/webtransport.d.ts +12 -0
- package/build/transports/webtransport.js +63 -0
- package/build/transports-uws/index.d.ts +7 -0
- package/build/transports-uws/index.js +8 -0
- package/build/transports-uws/polling.d.ts +99 -0
- package/build/transports-uws/polling.js +364 -0
- package/build/transports-uws/websocket.d.ts +32 -0
- package/build/transports-uws/websocket.js +73 -0
- package/build/userver.d.ts +42 -0
- package/build/userver.js +279 -0
- package/package.json +71 -0
- package/wrapper.mjs +10 -0
package/build/userver.js
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.uServer = void 0;
|
|
4
|
+
const debug_1 = require("debug");
|
|
5
|
+
const server_1 = require("./server");
|
|
6
|
+
const transports_uws_1 = require("./transports-uws");
|
|
7
|
+
const debug = (0, debug_1.default)("engine:uws");
|
|
8
|
+
/**
|
|
9
|
+
* An Engine.IO server based on the `uWebSockets.js` package.
|
|
10
|
+
*/
|
|
11
|
+
// TODO export it into its own package
|
|
12
|
+
class uServer extends server_1.BaseServer {
|
|
13
|
+
init() { }
|
|
14
|
+
cleanup() { }
|
|
15
|
+
/**
|
|
16
|
+
* Prepares a request by processing the query string.
|
|
17
|
+
*
|
|
18
|
+
* @private
|
|
19
|
+
*/
|
|
20
|
+
prepare(req, res) {
|
|
21
|
+
req.method = req.getMethod().toUpperCase();
|
|
22
|
+
req.url = req.getUrl();
|
|
23
|
+
const params = new URLSearchParams(req.getQuery());
|
|
24
|
+
req._query = Object.fromEntries(params.entries());
|
|
25
|
+
req.headers = {};
|
|
26
|
+
req.forEach((key, value) => {
|
|
27
|
+
req.headers[key] = value;
|
|
28
|
+
});
|
|
29
|
+
req.connection = {
|
|
30
|
+
remoteAddress: Buffer.from(res.getRemoteAddressAsText()).toString(),
|
|
31
|
+
};
|
|
32
|
+
res.onAborted(() => {
|
|
33
|
+
debug("response has been aborted");
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
createTransport(transportName, req) {
|
|
37
|
+
return new transports_uws_1.default[transportName](req);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Attach the engine to a µWebSockets.js server
|
|
41
|
+
* @param app
|
|
42
|
+
* @param options
|
|
43
|
+
*/
|
|
44
|
+
attach(app /* : TemplatedApp */, options = {}) {
|
|
45
|
+
const path = this._computePath(options);
|
|
46
|
+
app
|
|
47
|
+
.any(path, this.handleRequest.bind(this))
|
|
48
|
+
//
|
|
49
|
+
.ws(path, {
|
|
50
|
+
compression: options.compression,
|
|
51
|
+
idleTimeout: options.idleTimeout,
|
|
52
|
+
maxBackpressure: options.maxBackpressure,
|
|
53
|
+
maxPayloadLength: this.opts.maxHttpBufferSize,
|
|
54
|
+
upgrade: this.handleUpgrade.bind(this),
|
|
55
|
+
open: (ws) => {
|
|
56
|
+
const transport = ws.getUserData().transport;
|
|
57
|
+
transport.socket = ws;
|
|
58
|
+
transport.writable = true;
|
|
59
|
+
transport.emit("ready");
|
|
60
|
+
},
|
|
61
|
+
message: (ws, message, isBinary) => {
|
|
62
|
+
ws.getUserData().transport.onData(isBinary ? message : Buffer.from(message).toString());
|
|
63
|
+
},
|
|
64
|
+
close: (ws, code, message) => {
|
|
65
|
+
ws.getUserData().transport.onClose(code, message);
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
_applyMiddlewares(req, res, callback) {
|
|
70
|
+
if (this.middlewares.length === 0) {
|
|
71
|
+
return callback();
|
|
72
|
+
}
|
|
73
|
+
// needed to buffer headers until the status is computed
|
|
74
|
+
req.res = new ResponseWrapper(res);
|
|
75
|
+
super._applyMiddlewares(req, req.res, (err) => {
|
|
76
|
+
// some middlewares (like express-session) wait for the writeHead() call to flush their headers
|
|
77
|
+
// see https://github.com/expressjs/session/blob/1010fadc2f071ddf2add94235d72224cf65159c6/index.js#L220-L244
|
|
78
|
+
req.res.writeHead();
|
|
79
|
+
callback(err);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
handleRequest(res, req) {
|
|
83
|
+
debug('handling "%s" http request "%s"', req.getMethod(), req.getUrl());
|
|
84
|
+
this.prepare(req, res);
|
|
85
|
+
req.res = res;
|
|
86
|
+
const callback = (errorCode, errorContext) => {
|
|
87
|
+
if (errorCode !== undefined) {
|
|
88
|
+
this.emit("connection_error", {
|
|
89
|
+
req,
|
|
90
|
+
code: errorCode,
|
|
91
|
+
message: server_1.Server.errorMessages[errorCode],
|
|
92
|
+
context: errorContext,
|
|
93
|
+
});
|
|
94
|
+
this.abortRequest(req.res, errorCode, errorContext);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (req._query.sid) {
|
|
98
|
+
debug("setting new request for existing client");
|
|
99
|
+
// @ts-ignore
|
|
100
|
+
this.clients[req._query.sid].transport.onRequest(req);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
const closeConnection = (errorCode, errorContext) => this.abortRequest(res, errorCode, errorContext);
|
|
104
|
+
this.handshake(req._query.transport, req, closeConnection);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
this._applyMiddlewares(req, res, (err) => {
|
|
108
|
+
if (err) {
|
|
109
|
+
callback(server_1.Server.errors.BAD_REQUEST, { name: "MIDDLEWARE_FAILURE" });
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
this.verify(req, false, callback);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
handleUpgrade(res, req, context) {
|
|
117
|
+
debug("on upgrade");
|
|
118
|
+
this.prepare(req, res);
|
|
119
|
+
req.res = res;
|
|
120
|
+
const callback = async (errorCode, errorContext) => {
|
|
121
|
+
if (errorCode !== undefined) {
|
|
122
|
+
this.emit("connection_error", {
|
|
123
|
+
req,
|
|
124
|
+
code: errorCode,
|
|
125
|
+
message: server_1.Server.errorMessages[errorCode],
|
|
126
|
+
context: errorContext,
|
|
127
|
+
});
|
|
128
|
+
this.abortRequest(res, errorCode, errorContext);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const id = req._query.sid;
|
|
132
|
+
let transport;
|
|
133
|
+
if (id) {
|
|
134
|
+
const client = this.clients[id];
|
|
135
|
+
if (!client) {
|
|
136
|
+
debug("upgrade attempt for closed client");
|
|
137
|
+
return res.close();
|
|
138
|
+
}
|
|
139
|
+
else if (client.upgrading) {
|
|
140
|
+
debug("transport has already been trying to upgrade");
|
|
141
|
+
return res.close();
|
|
142
|
+
}
|
|
143
|
+
else if (client.upgraded) {
|
|
144
|
+
debug("transport had already been upgraded");
|
|
145
|
+
return res.close();
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
debug("upgrading existing transport");
|
|
149
|
+
transport = this.createTransport(req._query.transport, req);
|
|
150
|
+
client._maybeUpgrade(transport);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
transport = await this.handshake(req._query.transport, req, (errorCode, errorContext) => this.abortRequest(res, errorCode, errorContext));
|
|
155
|
+
if (!transport) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// calling writeStatus() triggers the flushing of any header added in a middleware
|
|
160
|
+
req.res.writeStatus("101 Switching Protocols");
|
|
161
|
+
res.upgrade({
|
|
162
|
+
transport,
|
|
163
|
+
}, req.getHeader("sec-websocket-key"), req.getHeader("sec-websocket-protocol"), req.getHeader("sec-websocket-extensions"), context);
|
|
164
|
+
};
|
|
165
|
+
this._applyMiddlewares(req, res, (err) => {
|
|
166
|
+
if (err) {
|
|
167
|
+
callback(server_1.Server.errors.BAD_REQUEST, { name: "MIDDLEWARE_FAILURE" });
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
this.verify(req, true, callback);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
abortRequest(res, errorCode, errorContext) {
|
|
175
|
+
const statusCode = errorCode === server_1.Server.errors.FORBIDDEN
|
|
176
|
+
? "403 Forbidden"
|
|
177
|
+
: "400 Bad Request";
|
|
178
|
+
const message = errorContext && errorContext.message
|
|
179
|
+
? errorContext.message
|
|
180
|
+
: server_1.Server.errorMessages[errorCode];
|
|
181
|
+
res.writeStatus(statusCode);
|
|
182
|
+
res.writeHeader("Content-Type", "application/json");
|
|
183
|
+
res.end(JSON.stringify({
|
|
184
|
+
code: errorCode,
|
|
185
|
+
message,
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
exports.uServer = uServer;
|
|
190
|
+
class ResponseWrapper {
|
|
191
|
+
constructor(res) {
|
|
192
|
+
this.res = res;
|
|
193
|
+
this.statusWritten = false;
|
|
194
|
+
this.headers = [];
|
|
195
|
+
this.isAborted = false;
|
|
196
|
+
}
|
|
197
|
+
set statusCode(status) {
|
|
198
|
+
if (!status) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
// FIXME: handle all status codes?
|
|
202
|
+
this.writeStatus(status === 200 ? "200 OK" : "204 No Content");
|
|
203
|
+
}
|
|
204
|
+
writeHead(status) {
|
|
205
|
+
this.statusCode = status;
|
|
206
|
+
}
|
|
207
|
+
setHeader(key, value) {
|
|
208
|
+
if (Array.isArray(value)) {
|
|
209
|
+
value.forEach((val) => {
|
|
210
|
+
this.writeHeader(key, val);
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
this.writeHeader(key, value);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
removeHeader() {
|
|
218
|
+
// FIXME: not implemented
|
|
219
|
+
}
|
|
220
|
+
// needed by vary: https://github.com/jshttp/vary/blob/5d725d059b3871025cf753e9dfa08924d0bcfa8f/index.js#L134
|
|
221
|
+
getHeader() { }
|
|
222
|
+
writeStatus(status) {
|
|
223
|
+
if (this.isAborted)
|
|
224
|
+
return;
|
|
225
|
+
this.res.writeStatus(status);
|
|
226
|
+
this.statusWritten = true;
|
|
227
|
+
this.writeBufferedHeaders();
|
|
228
|
+
return this;
|
|
229
|
+
}
|
|
230
|
+
writeHeader(key, value) {
|
|
231
|
+
if (this.isAborted)
|
|
232
|
+
return;
|
|
233
|
+
if (key === "Content-Length") {
|
|
234
|
+
// the content length is automatically added by uWebSockets.js
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (this.statusWritten) {
|
|
238
|
+
this.res.writeHeader(key, value);
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
this.headers.push([key, value]);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
writeBufferedHeaders() {
|
|
245
|
+
this.headers.forEach(([key, value]) => {
|
|
246
|
+
this.res.writeHeader(key, value);
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
end(data) {
|
|
250
|
+
if (this.isAborted)
|
|
251
|
+
return;
|
|
252
|
+
this.res.cork(() => {
|
|
253
|
+
if (!this.statusWritten) {
|
|
254
|
+
// status will be inferred as "200 OK"
|
|
255
|
+
this.writeBufferedHeaders();
|
|
256
|
+
}
|
|
257
|
+
this.res.end(data);
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
onData(fn) {
|
|
261
|
+
if (this.isAborted)
|
|
262
|
+
return;
|
|
263
|
+
this.res.onData(fn);
|
|
264
|
+
}
|
|
265
|
+
onAborted(fn) {
|
|
266
|
+
if (this.isAborted)
|
|
267
|
+
return;
|
|
268
|
+
this.res.onAborted(() => {
|
|
269
|
+
// Any attempt to use the UWS response object after abort will throw!
|
|
270
|
+
this.isAborted = true;
|
|
271
|
+
fn();
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
cork(fn) {
|
|
275
|
+
if (this.isAborted)
|
|
276
|
+
return;
|
|
277
|
+
this.res.cork(fn);
|
|
278
|
+
}
|
|
279
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gleamkit/engine.io",
|
|
3
|
+
"version": "6.6.3",
|
|
4
|
+
"description": "The realtime engine behind Socket.IO. Provides the foundation of a bidirectional connection between client and server",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"main": "./build/engine.io.js",
|
|
7
|
+
"types": "./build/engine.io.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
"types": "./build/engine.io.d.ts",
|
|
10
|
+
"import": "./wrapper.mjs",
|
|
11
|
+
"require": "./build/engine.io.js"
|
|
12
|
+
},
|
|
13
|
+
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
14
|
+
"contributors": [
|
|
15
|
+
{
|
|
16
|
+
"name": "Eugen Dueck",
|
|
17
|
+
"web": "https://github.com/EugenDueck"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "Afshin Mehrabani",
|
|
21
|
+
"web": "https://github.com/afshinm"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "Christoph Dorn",
|
|
25
|
+
"web": "https://github.com/cadorn"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "Mark Mokryn",
|
|
29
|
+
"email": "mokesmokes@gmail.com"
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@types/cookie": "^0.4.1",
|
|
35
|
+
"@types/cors": "^2.8.12",
|
|
36
|
+
"@types/node": ">=10.0.0",
|
|
37
|
+
"accepts": "~1.3.4",
|
|
38
|
+
"base64id": "2.0.0",
|
|
39
|
+
"cookie": "~0.7.2",
|
|
40
|
+
"cors": "~2.8.5",
|
|
41
|
+
"debug": "~4.3.1",
|
|
42
|
+
"engine.io-parser": "~5.2.1",
|
|
43
|
+
"ws": "npm:@gleamkit/ws@8.21.1"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"compile": "rimraf ./build && tsc",
|
|
47
|
+
"test": "npm run compile && npm run format:check && npm run test:default && npm run test:compat-v3",
|
|
48
|
+
"test:default": "mocha --bail --exit",
|
|
49
|
+
"test:compat-v3": "EIO_CLIENT=3 mocha --exit",
|
|
50
|
+
"test:eiows": "EIO_WS_ENGINE=eiows mocha --exit",
|
|
51
|
+
"test:uws": "EIO_WS_ENGINE=uws mocha --exit",
|
|
52
|
+
"format:check": "prettier --check \"wrapper.mjs\" \"lib/**/*.ts\" \"test/**/*.js\" \"test/webtransport.mjs\"",
|
|
53
|
+
"format:fix": "prettier --write \"wrapper.mjs\" \"lib/**/*.ts\" \"test/**/*.js\" \"test/webtransport.mjs\"",
|
|
54
|
+
"prepack": "echo 'skip compile — build already present'"
|
|
55
|
+
},
|
|
56
|
+
"homepage": "https://github.com/socketio/socket.io/tree/main/packages/engine.io#readme",
|
|
57
|
+
"repository": {
|
|
58
|
+
"type": "git",
|
|
59
|
+
"url": "git+https://github.com/socketio/socket.io.git"
|
|
60
|
+
},
|
|
61
|
+
"bugs": {
|
|
62
|
+
"url": "https://github.com/socketio/socket.io/issues"
|
|
63
|
+
},
|
|
64
|
+
"files": [
|
|
65
|
+
"build/",
|
|
66
|
+
"wrapper.mjs"
|
|
67
|
+
],
|
|
68
|
+
"engines": {
|
|
69
|
+
"node": ">=10.2.0"
|
|
70
|
+
}
|
|
71
|
+
}
|