Compare commits

...

8 Commits
4.6.2 ... 4.7.0

Author SHA1 Message Date
Damien Arrachequesne
00d8ee5b05 chore(release): 4.7.0
Diff: https://github.com/socketio/socket.io/compare/4.6.2...4.7.0
2023-06-22 11:27:45 +02:00
Damien Arrachequesne
2dd5fa9dd4 ci: add Node.js 20 in the test matrix
Reference: https://github.com/nodejs/Release
2023-06-22 07:55:32 +02:00
Damien Arrachequesne
a5dff0ac83 docs(examples): increase httpd ProxyTimeout value (2) 2023-06-21 00:07:44 +02:00
Damien Arrachequesne
3035c25982 docs(examples): increase httpd ProxyTimeout value
With a value that is too small, the HTTP long-polling request receives
an HTTP 502 response code and the connection gets closed.
2023-06-20 23:57:46 +02:00
Damien Arrachequesne
63f181cc12 feat: serve client bundles with CORS headers
The version of the `cors` package matches the one used by `engine.io`.

Related: https://github.com/socketio/socket.io/issues/3552
2023-06-20 14:32:59 +02:00
Damien Arrachequesne
a250e283da chore: bump engine.io to version 6.5.0
Diff: https://github.com/socketio/engine.io/compare/6.4.2...6.5.0
Release notes: https://github.com/socketio/engine.io/releases/tag/6.5.0
2023-06-20 09:17:10 +02:00
SyedTayyabUlMazhar
e5c62cad60 fix: remove the Partial modifier from the socket.data type (#4740)
Wrapping SocketData with Partial causes issues when reading data even
if you've made sure to pass all values. If someone want to make their
type Partial or make only a few properties optional, they can do so in
their own type instead.

Related: https://github.com/socketio/socket.io/issues/4537
2023-06-20 07:49:02 +02:00
Damien Arrachequesne
01d37624a8 docs(changelog): update the version range of the engine.io dependency 2023-05-31 11:28:00 +02:00
17 changed files with 484 additions and 158 deletions

View File

@@ -16,7 +16,9 @@ jobs:
strategy:
matrix:
node-version: [12, 14, 16]
node-version:
- 16
- 20
steps:
- name: Checkout repository

View File

@@ -2,6 +2,7 @@
## 2023
- [4.7.0](#470-2023-06-22) (Jun 2023)
- [4.6.2](#462-2023-05-31) (May 2023)
- [4.6.1](#461-2023-02-20) (Feb 2023)
- [4.6.0](#460-2023-02-07) (Feb 2023)
@@ -58,6 +59,92 @@
# Release notes
## [4.7.0](https://github.com/socketio/socket.io/compare/4.6.2...4.7.0) (2023-06-22)
### Bug Fixes
* remove the Partial modifier from the socket.data type ([#4740](https://github.com/socketio/socket.io/issues/4740)) ([e5c62ca](https://github.com/socketio/socket.io/commit/e5c62cad60fc7d16fbb024fd9be1d1880f4e6f5f))
### Features
#### Support for WebTransport
The Engine.IO server can now use WebTransport as the underlying transport.
WebTransport is a web API that uses the HTTP/3 protocol as a bidirectional transport. It's intended for two-way communications between a web client and an HTTP/3 server.
References:
- https://w3c.github.io/webtransport/
- https://developer.mozilla.org/en-US/docs/Web/API/WebTransport
- https://developer.chrome.com/articles/webtransport/
Until WebTransport support lands [in Node.js](https://github.com/nodejs/node/issues/38478), you can use the `@fails-components/webtransport` package:
```js
import { readFileSync } from "fs";
import { createServer } from "https";
import { Server } from "socket.io";
import { Http3Server } from "@fails-components/webtransport";
// WARNING: the total length of the validity period MUST NOT exceed two weeks (https://w3c.github.io/webtransport/#custom-certificate-requirements)
const cert = readFileSync("/path/to/my/cert.pem");
const key = readFileSync("/path/to/my/key.pem");
const httpsServer = createServer({
key,
cert
});
httpsServer.listen(3000);
const io = new Server(httpsServer, {
transports: ["polling", "websocket", "webtransport"] // WebTransport is not enabled by default
});
const h3Server = new Http3Server({
port: 3000,
host: "0.0.0.0",
secret: "changeit",
cert,
privKey: key,
});
(async () => {
const stream = await h3Server.sessionStream("/engine.io/");
const sessionReader = stream.getReader();
while (true) {
const { done, value } = await sessionReader.read();
if (done) {
break;
}
io.engine.onWebTransportSession(value);
}
})();
h3Server.startServer();
```
Added in [123b68c](https://github.com/socketio/engine.io/commit/123b68c04f9e971f59b526e0f967a488ee6b0116).
#### Client bundles with CORS headers
The bundles will now have the right `Access-Control-Allow-xxx` headers.
Added in [63f181c](https://github.com/socketio/socket.io/commit/63f181cc12cbbbf94ed40eef52d60f36a1214fbe).
### Dependencies
- [`engine.io@~6.4.2`](https://github.com/socketio/engine.io/releases/tag/6.5.0) ([diff](https://github.com/socketio/engine.io/compare/6.4.2...6.5.0))
- [`ws@~8.11.0`](https://github.com/websockets/ws/releases/tag/8.11.0) (no change)
## [4.6.2](https://github.com/socketio/socket.io/compare/4.6.1...4.6.2) (2023-05-31)
@@ -68,7 +155,7 @@
### Dependencies
- [`engine.io@~6.4.0`](https://github.com/socketio/engine.io/releases/tag/6.4.0) (no change)
- [`engine.io@~6.4.2`](https://github.com/socketio/engine.io/releases/tag/6.4.0) ([diff](https://github.com/socketio/engine.io/compare/6.4.1...6.4.2))
- [`ws@~8.11.0`](https://github.com/websockets/ws/releases/tag/8.11.0) (no change)
@@ -84,7 +171,7 @@
### Dependencies
- [`engine.io@~6.4.0`](https://github.com/socketio/engine.io/releases/tag/6.4.0) (no change)
- [`engine.io@~6.4.1`](https://github.com/socketio/engine.io/releases/tag/6.4.1) ([diff](https://github.com/socketio/engine.io/compare/6.4.0...6.4.1))
- [`ws@~8.11.0`](https://github.com/websockets/ws/releases/tag/8.11.0) (no change)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
/*!
* Socket.IO v4.6.2
* Socket.IO v4.7.0
* (c) 2014-2023 Guillermo Rauch
* Released under the MIT License.
*/
@@ -355,12 +355,40 @@
fileReader.onload = function () {
var content = fileReader.result.split(",")[1];
callback("b" + content);
callback("b" + (content || ""));
};
return fileReader.readAsDataURL(data);
};
function toArray(data) {
if (data instanceof Uint8Array) {
return data;
} else if (data instanceof ArrayBuffer) {
return new Uint8Array(data);
} else {
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
}
}
var TEXT_ENCODER;
function encodePacketToBinary(packet, callback) {
if (withNativeBlob$1 && packet.data instanceof Blob) {
return packet.data.arrayBuffer().then(toArray).then(callback);
} else if (withNativeArrayBuffer$2 && (packet.data instanceof ArrayBuffer || isView$1(packet.data))) {
return callback(toArray(packet.data));
}
encodePacket(packet, false, function (encoded) {
if (!TEXT_ENCODER) {
TEXT_ENCODER = new TextEncoder();
}
callback(TEXT_ENCODER.encode(encoded));
});
}
// imported from https://github.com/socketio/base64-arraybuffer
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; // Use a lookup table to find the index.
var lookup$1 = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);
@@ -403,7 +431,6 @@
};
var withNativeArrayBuffer$1 = typeof ArrayBuffer === "function";
var decodePacket = function decodePacket(encodedPacket, binaryType) {
if (typeof encodedPacket !== "string") {
return {
@@ -450,12 +477,24 @@
var mapBinary = function mapBinary(data, binaryType) {
switch (binaryType) {
case "blob":
return data instanceof ArrayBuffer ? new Blob([data]) : data;
if (data instanceof Blob) {
// from WebSocket + binaryType "blob"
return data;
} else {
// from HTTP long-polling or WebTransport
return new Blob([data]);
}
case "arraybuffer":
default:
return data;
// assuming the data is already an ArrayBuffer
if (data instanceof ArrayBuffer) {
// from HTTP long-polling (base64) or WebSocket + binaryType "arraybuffer"
return data;
} else {
// from WebTransport (Uint8Array)
return data.buffer;
}
}
};
@@ -494,6 +533,18 @@
return packets;
};
var TEXT_DECODER;
function decodePacketFromBinary(data, isBinary, binaryType) {
if (!TEXT_DECODER) {
// lazily created for compatibility with old browser platforms
TEXT_DECODER = new TextDecoder();
} // 48 === "0".charCodeAt(0) (OPEN packet type)
// 54 === "6".charCodeAt(0) (NOOP packet type)
var isPlainBinary = isBinary || data[0] < 48 || data[0] > 54;
return decodePacket(isPlainBinary ? data : TEXT_DECODER.decode(data), binaryType);
}
var protocol$1 = 4;
/**
@@ -728,6 +779,46 @@
return length;
}
// imported from https://github.com/galkn/querystring
/**
* Compiles a querystring
* Returns string representation of the object
*
* @param {Object}
* @api private
*/
function encode$1(obj) {
var str = '';
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
if (str.length) str += '&';
str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
}
}
return str;
}
/**
* Parses a simple querystring into an object
*
* @param {String} qs
* @api private
*/
function decode(qs) {
var qry = {};
var pairs = qs.split('&');
for (var i = 0, l = pairs.length; i < l; i++) {
var pair = pairs[i].split('=');
qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
}
return qry;
}
var TransportError = /*#__PURE__*/function (_Error) {
_inherits(TransportError, _Error);
@@ -888,6 +979,33 @@
}, {
key: "pause",
value: function pause(onPause) {}
}, {
key: "createUri",
value: function createUri(schema) {
var query = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return schema + "://" + this._hostname() + this._port() + this.opts.path + this._query(query);
}
}, {
key: "_hostname",
value: function _hostname() {
var hostname = this.opts.hostname;
return hostname.indexOf(":") === -1 ? hostname : "[" + hostname + "]";
}
}, {
key: "_port",
value: function _port() {
if (this.opts.port && (this.opts.secure && Number(this.opts.port !== 443) || !this.opts.secure && Number(this.opts.port) !== 80)) {
return ":" + this.opts.port;
} else {
return "";
}
}
}, {
key: "_query",
value: function _query(query) {
var encodedQuery = encode$1(query);
return encodedQuery.length ? "?" + encodedQuery : "";
}
}]);
return Transport;
@@ -909,7 +1027,7 @@
* @api public
*/
function encode$1(num) {
function encode(num) {
var encoded = '';
do {
@@ -927,9 +1045,9 @@
*/
function yeast() {
var now = encode$1(+new Date());
var now = encode(+new Date());
if (now !== prev) return seed = 0, prev = now;
return now + '.' + encode$1(seed++);
return now + '.' + encode(seed++);
} //
// Map each character to its index.
//
@@ -938,46 +1056,6 @@
map[alphabet[i]] = i;
}
// imported from https://github.com/galkn/querystring
/**
* Compiles a querystring
* Returns string representation of the object
*
* @param {Object}
* @api private
*/
function encode(obj) {
var str = '';
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
if (str.length) str += '&';
str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
}
}
return str;
}
/**
* Parses a simple querystring into an object
*
* @param {String} qs
* @api private
*/
function decode(qs) {
var qry = {};
var pairs = qs.split('&');
for (var i = 0, l = pairs.length; i < l; i++) {
var pair = pairs[i].split('=');
qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
}
return qry;
}
// imported from https://github.com/component/has-cors
var value = false;
@@ -1005,6 +1083,7 @@
} catch (e) {}
}
}
function createCookieJar() {}
function empty() {}
@@ -1043,7 +1122,6 @@
}
_this.xd = typeof location !== "undefined" && opts.hostname !== location.hostname || port !== opts.port;
_this.xs = opts.secure !== isSSL;
}
/**
* XHR supports binary
@@ -1052,6 +1130,11 @@
var forceBase64 = opts && opts.forceBase64;
_this.supportsBinary = hasXHR2 && !forceBase64;
if (_this.opts.withCredentials) {
_this.cookieJar = createCookieJar();
}
return _this;
}
@@ -1222,9 +1305,8 @@
}, {
key: "uri",
value: function uri() {
var query = this.query || {};
var schema = this.opts.secure ? "https" : "http";
var port = ""; // cache busting is forced
var query = this.query || {}; // cache busting is forced
if (false !== this.opts.timestampRequests) {
query[this.opts.timestampParam] = yeast();
@@ -1232,16 +1314,9 @@
if (!this.supportsBinary && !query.sid) {
query.b64 = 1;
} // avoid port if default for schema
if (this.opts.port && ("https" === schema && Number(this.opts.port) !== 443 || "http" === schema && Number(this.opts.port) !== 80)) {
port = ":" + this.opts.port;
}
var encodedQuery = encode(query);
var ipv6 = this.opts.hostname.indexOf(":") !== -1;
return schema + "://" + (ipv6 ? "[" + this.opts.hostname + "]" : this.opts.hostname) + port + this.opts.path + (encodedQuery.length ? "?" + encodedQuery : "");
return this.createUri(schema, query);
}
/**
* Creates a request.
@@ -1257,7 +1332,7 @@
_extends(opts, {
xd: this.xd,
xs: this.xs
cookieJar: this.cookieJar
}, this.opts);
return new Request(this.uri(), opts);
@@ -1327,7 +1402,6 @@
_this8.opts = opts;
_this8.method = opts.method || "GET";
_this8.uri = uri;
_this8.async = false !== opts.async;
_this8.data = undefined !== opts.data ? opts.data : null;
_this8.create();
@@ -1346,13 +1420,14 @@
value: function create() {
var _this9 = this;
var _a;
var opts = pick(this.opts, "agent", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "autoUnref");
opts.xdomain = !!this.opts.xd;
opts.xscheme = !!this.opts.xs;
var xhr = this.xhr = new XHR(opts);
try {
xhr.open(this.method, this.uri, this.async);
xhr.open(this.method, this.uri, true);
try {
if (this.opts.extraHeaders) {
@@ -1374,8 +1449,9 @@
try {
xhr.setRequestHeader("Accept", "*/*");
} catch (e) {} // ie6 check
} catch (e) {}
(_a = this.opts.cookieJar) === null || _a === void 0 ? void 0 : _a.addCookies(xhr); // ie6 check
if ("withCredentials" in xhr) {
xhr.withCredentials = this.opts.withCredentials;
@@ -1386,6 +1462,12 @@
}
xhr.onreadystatechange = function () {
var _a;
if (xhr.readyState === 3) {
(_a = _this9.opts.cookieJar) === null || _a === void 0 ? void 0 : _a.parseCookies(xhr);
}
if (4 !== xhr.readyState) return;
if (200 === xhr.status || 1223 === xhr.status) {
@@ -1675,14 +1757,8 @@
}, {
key: "uri",
value: function uri() {
var query = this.query || {};
var schema = this.opts.secure ? "wss" : "ws";
var port = ""; // avoid port if default for schema
if (this.opts.port && ("wss" === schema && Number(this.opts.port) !== 443 || "ws" === schema && Number(this.opts.port) !== 80)) {
port = ":" + this.opts.port;
} // append timestamp to URI
var query = this.query || {}; // append timestamp to URI
if (this.opts.timestampRequests) {
query[this.opts.timestampParam] = yeast();
@@ -1693,9 +1769,7 @@
query.b64 = 1;
}
var encodedQuery = encode(query);
var ipv6 = this.opts.hostname.indexOf(":") !== -1;
return schema + "://" + (ipv6 ? "[" + this.opts.hostname + "]" : this.opts.hostname) + port + this.opts.path + (encodedQuery.length ? "?" + encodedQuery : "");
return this.createUri(schema, query);
}
/**
* Feature detection for WebSocket.
@@ -1714,8 +1788,127 @@
return WS;
}(Transport);
function shouldIncludeBinaryHeader(packet, encoded) {
// 48 === "0".charCodeAt(0) (OPEN packet type)
// 54 === "6".charCodeAt(0) (NOOP packet type)
return packet.type === "message" && typeof packet.data !== "string" && encoded[0] >= 48 && encoded[0] <= 54;
}
var WT = /*#__PURE__*/function (_Transport) {
_inherits(WT, _Transport);
var _super = _createSuper(WT);
function WT() {
_classCallCheck(this, WT);
return _super.apply(this, arguments);
}
_createClass(WT, [{
key: "name",
get: function get() {
return "webtransport";
}
}, {
key: "doOpen",
value: function doOpen() {
var _this = this;
// @ts-ignore
if (typeof WebTransport !== "function") {
return;
} // @ts-ignore
this.transport = new WebTransport(this.createUri("https"), this.opts.transportOptions[this.name]);
this.transport.closed.then(function () {
return _this.onClose();
}); // note: we could have used async/await, but that would require some additional polyfills
this.transport.ready.then(function () {
_this.transport.createBidirectionalStream().then(function (stream) {
var reader = stream.readable.getReader();
_this.writer = stream.writable.getWriter();
var binaryFlag;
var read = function read() {
reader.read().then(function (_ref) {
var done = _ref.done,
value = _ref.value;
if (done) {
return;
}
if (!binaryFlag && value.byteLength === 1 && value[0] === 54) {
binaryFlag = true;
} else {
// TODO expose binarytype
_this.onPacket(decodePacketFromBinary(value, binaryFlag, "arraybuffer"));
binaryFlag = false;
}
read();
});
};
read();
var handshake = _this.query.sid ? "0{\"sid\":\"".concat(_this.query.sid, "\"}") : "0";
_this.writer.write(new TextEncoder().encode(handshake)).then(function () {
return _this.onOpen();
});
});
});
}
}, {
key: "write",
value: function write(packets) {
var _this2 = this;
this.writable = false;
var _loop = function _loop(i) {
var packet = packets[i];
var lastPacket = i === packets.length - 1;
encodePacketToBinary(packet, function (data) {
if (shouldIncludeBinaryHeader(packet, data)) {
_this2.writer.write(Uint8Array.of(54));
}
_this2.writer.write(data).then(function () {
if (lastPacket) {
nextTick(function () {
_this2.writable = true;
_this2.emitReserved("drain");
}, _this2.setTimeoutFn);
}
});
});
};
for (var i = 0; i < packets.length; i++) {
_loop(i);
}
}
}, {
key: "doClose",
value: function doClose() {
var _a;
(_a = this.transport) === null || _a === void 0 ? void 0 : _a.close();
}
}]);
return WT;
}(Transport);
var transports = {
websocket: WS,
webtransport: WT,
polling: Polling
};
@@ -1841,7 +2034,7 @@
_this.hostname = opts.hostname || (typeof location !== "undefined" ? location.hostname : "localhost");
_this.port = opts.port || (typeof location !== "undefined" && location.port ? location.port : _this.secure ? "443" : "80");
_this.transports = opts.transports || ["polling", "websocket"];
_this.transports = opts.transports || ["polling", "websocket", "webtransport"];
_this.writeBuffer = [];
_this.prevBufferLen = 0;
_this.opts = _extends({
@@ -2108,7 +2301,17 @@
transport.once("close", onTransportClose);
this.once("close", onclose);
this.once("upgrading", onupgrade);
transport.open();
if (this.upgrades.indexOf("webtransport") !== -1 && name !== "webtransport") {
// favor WebTransport
this.setTimeoutFn(function () {
if (!failed) {
transport.open();
}
}, 200);
} else {
transport.open();
}
}
/**
* Called when connection is deemed open.
@@ -4381,11 +4584,12 @@
var openSubDestroy = on(socket, "open", function () {
self.onopen();
fn && fn();
}); // emit `error`
});
var errorSub = on(socket, "error", function (err) {
self.cleanup();
self._readyState = "closed";
var onError = function onError(err) {
_this2.cleanup();
_this2._readyState = "closed";
_this2.emitReserved("error", err);
@@ -4393,31 +4597,28 @@
fn(err);
} else {
// Only do this if there is no fn to handle the error
self.maybeReconnectOnOpen();
_this2.maybeReconnectOnOpen();
}
});
}; // emit `error`
var errorSub = on(socket, "error", onError);
if (false !== this._timeout) {
var timeout = this._timeout;
if (timeout === 0) {
openSubDestroy(); // prevents a race condition with the 'open' event
} // set timer
var timeout = this._timeout; // set timer
var timer = this.setTimeoutFn(function () {
openSubDestroy();
socket.close(); // @ts-ignore
socket.emit("error", new Error("timeout"));
onError(new Error("timeout"));
socket.close();
}, timeout);
if (this.opts.autoUnref) {
timer.unref();
}
this.subs.push(function subDestroy() {
clearTimeout(timer);
this.subs.push(function () {
_this2.clearTimeoutFn(timer);
});
}
@@ -4670,8 +4871,8 @@
timer.unref();
}
this.subs.push(function subDestroy() {
clearTimeout(timer);
this.subs.push(function () {
_this4.clearTimeoutFn(timer);
});
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -51,4 +51,5 @@ RewriteRule /(.*) balancer://nodes_ws/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule /(.*) balancer://nodes_polling/$1 [P,L]
ProxyTimeout 3
# must be bigger than pingInterval (25s by default) + pingTimeout (20s by default)
ProxyTimeout 60

View File

@@ -40,6 +40,7 @@ import {
SecondArg,
} from "./typed-events";
import { patchAdapter, restoreAdapter, serveFile } from "./uws";
import corsMiddleware from "cors";
const debug = debugModule("socket.io:server");
@@ -202,6 +203,11 @@ export class Server<
*/
_connectTimeout: number;
private httpServer: http.Server | HTTPSServer | Http2SecureServer;
private _corsMiddleware: (
req: http.IncomingMessage,
res: http.ServerResponse,
next: () => void
) => void;
/**
* Server constructor.
@@ -267,6 +273,10 @@ export class Server<
this.attach(
srv as http.Server | HTTPSServer | Http2SecureServer | number
);
if (this.opts.cors) {
this._corsMiddleware = corsMiddleware(this.opts.cors);
}
}
get _opts() {
@@ -548,7 +558,13 @@ export class Server<
srv.removeAllListeners("request");
srv.on("request", (req, res) => {
if (this.clientPathRegex.test(req.url!)) {
this.serve(req, res);
if (this._corsMiddleware) {
this._corsMiddleware(req, res, () => {
this.serve(req, res);
});
} else {
this.serve(req, res);
}
} else {
for (let i = 0; i < evs.length; i++) {
evs[i].call(srv, req, res);

View File

@@ -202,7 +202,7 @@ export class Socket<
* Additional information that can be attached to the Socket instance and which will be used in the
* {@link Server.fetchSockets()} method.
*/
public data: Partial<SocketData> = {};
public data: SocketData = {} as SocketData;
/**
* Whether the socket is currently connected or not.
*
@@ -260,7 +260,7 @@ export class Socket<
this.id = previousSession.sid;
this.pid = previousSession.pid;
previousSession.rooms.forEach((room) => this.join(room));
this.data = previousSession.data as Partial<SocketData>;
this.data = previousSession.data as SocketData;
previousSession.missedPackets.forEach((packet) => {
this.packet({
type: PacketType.EVENT,

75
package-lock.json generated
View File

@@ -11,8 +11,9 @@
"dependencies": {
"accepts": "~1.3.4",
"base64id": "~2.0.0",
"cors": "~2.8.5",
"debug": "~4.3.2",
"engine.io": "~6.4.2",
"engine.io": "~6.5.0",
"socket.io-adapter": "~2.5.2",
"socket.io-parser": "~4.2.4"
},
@@ -23,14 +24,14 @@
"nyc": "^15.1.0",
"prettier": "^2.3.2",
"rimraf": "^3.0.2",
"socket.io-client": "4.6.2",
"socket.io-client": "4.7.0",
"socket.io-client-v2": "npm:socket.io-client@^2.4.0",
"superagent": "^8.0.0",
"supertest": "^6.1.6",
"ts-node": "^10.2.1",
"tsd": "^0.21.0",
"typescript": "^4.4.2",
"uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.0.0"
"uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.30.0"
},
"engines": {
"node": ">=10.0.0"
@@ -1377,9 +1378,9 @@
"dev": true
},
"node_modules/engine.io": {
"version": "6.4.2",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz",
"integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==",
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.0.tgz",
"integrity": "sha512-UlfoK1iD62Hkedw2TmuHdhDsZCGaAyp+LZ/AvnImjYBeWagA3qIEETum90d6shMeFZiDuGT66zVCdx1wKYKGGg==",
"dependencies": {
"@types/cookie": "^0.4.1",
"@types/cors": "^2.8.12",
@@ -1389,7 +1390,7 @@
"cookie": "~0.4.1",
"cors": "~2.8.5",
"debug": "~4.3.1",
"engine.io-parser": "~5.0.3",
"engine.io-parser": "~5.1.0",
"ws": "~8.11.0"
},
"engines": {
@@ -1397,22 +1398,22 @@
}
},
"node_modules/engine.io-client": {
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.4.0.tgz",
"integrity": "sha512-GyKPDyoEha+XZ7iEqam49vz6auPnNJ9ZBfy89f+rMMas8AuiMWOZ9PVzu8xb9ZC6rafUqiGHSCfu22ih66E+1g==",
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.0.tgz",
"integrity": "sha512-C7eN3OKggSfd5g8IDgUA9guC8TNS6CEganKT7dL6Fp3q+FobcQ/WBn2Qq2XTL1vNTiFZfDzXohvqLuR9dWejdg==",
"dev": true,
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1",
"engine.io-parser": "~5.0.3",
"engine.io-parser": "~5.1.0",
"ws": "~8.11.0",
"xmlhttprequest-ssl": "~2.0.0"
}
},
"node_modules/engine.io-parser": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz",
"integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.1.0.tgz",
"integrity": "sha512-enySgNiK5tyZFynt3z7iqBR+Bto9EVVVvDFuTT0ioHCGbzirZVGDGiQjZzEp8hWl6hd5FSVytJGuScX1C1C35w==",
"engines": {
"node": ">=10.0.0"
}
@@ -3463,14 +3464,14 @@
}
},
"node_modules/socket.io-client": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.6.2.tgz",
"integrity": "sha512-OwWrMbbA8wSqhBAR0yoPK6EdQLERQAYjXb3A0zLpgxfM1ZGLKoxHx8gVmCHA6pcclRX5oA/zvQf7bghAS11jRA==",
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.0.tgz",
"integrity": "sha512-7Q8CeDrhuZzg4QLXl3tXlk5yb086oxYzehAVZRLiGCzCmtDneiHz1qHyyWcxhTgxXiokVpWQXoG/u60HoXSQew==",
"dev": true,
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.2",
"engine.io-client": "~6.4.0",
"engine.io-client": "~6.5.0",
"socket.io-parser": "~4.2.4"
},
"engines": {
@@ -4105,8 +4106,8 @@
}
},
"node_modules/uWebSockets.js": {
"version": "20.0.0",
"resolved": "git+https://git@github.com/uNetworking/uWebSockets.js.git#4558ee00f9f1f686fffe1accbfc2e85b1af9c50f",
"version": "20.30.0",
"resolved": "git+https://git@github.com/uNetworking/uWebSockets.js.git#d39d4181daf5b670d44cbc1b18f8c28c85fd4142",
"dev": true
},
"node_modules/v8-compile-cache-lib": {
@@ -5387,9 +5388,9 @@
"dev": true
},
"engine.io": {
"version": "6.4.2",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz",
"integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==",
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.0.tgz",
"integrity": "sha512-UlfoK1iD62Hkedw2TmuHdhDsZCGaAyp+LZ/AvnImjYBeWagA3qIEETum90d6shMeFZiDuGT66zVCdx1wKYKGGg==",
"requires": {
"@types/cookie": "^0.4.1",
"@types/cors": "^2.8.12",
@@ -5399,27 +5400,27 @@
"cookie": "~0.4.1",
"cors": "~2.8.5",
"debug": "~4.3.1",
"engine.io-parser": "~5.0.3",
"engine.io-parser": "~5.1.0",
"ws": "~8.11.0"
}
},
"engine.io-client": {
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.4.0.tgz",
"integrity": "sha512-GyKPDyoEha+XZ7iEqam49vz6auPnNJ9ZBfy89f+rMMas8AuiMWOZ9PVzu8xb9ZC6rafUqiGHSCfu22ih66E+1g==",
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.0.tgz",
"integrity": "sha512-C7eN3OKggSfd5g8IDgUA9guC8TNS6CEganKT7dL6Fp3q+FobcQ/WBn2Qq2XTL1vNTiFZfDzXohvqLuR9dWejdg==",
"dev": true,
"requires": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1",
"engine.io-parser": "~5.0.3",
"engine.io-parser": "~5.1.0",
"ws": "~8.11.0",
"xmlhttprequest-ssl": "~2.0.0"
}
},
"engine.io-parser": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz",
"integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg=="
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.1.0.tgz",
"integrity": "sha512-enySgNiK5tyZFynt3z7iqBR+Bto9EVVVvDFuTT0ioHCGbzirZVGDGiQjZzEp8hWl6hd5FSVytJGuScX1C1C35w=="
},
"error-ex": {
"version": "1.3.2",
@@ -6922,14 +6923,14 @@
}
},
"socket.io-client": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.6.2.tgz",
"integrity": "sha512-OwWrMbbA8wSqhBAR0yoPK6EdQLERQAYjXb3A0zLpgxfM1ZGLKoxHx8gVmCHA6pcclRX5oA/zvQf7bghAS11jRA==",
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.0.tgz",
"integrity": "sha512-7Q8CeDrhuZzg4QLXl3tXlk5yb086oxYzehAVZRLiGCzCmtDneiHz1qHyyWcxhTgxXiokVpWQXoG/u60HoXSQew==",
"dev": true,
"requires": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.2",
"engine.io-client": "~6.4.0",
"engine.io-client": "~6.5.0",
"socket.io-parser": "~4.2.4"
}
},
@@ -7402,9 +7403,9 @@
"dev": true
},
"uWebSockets.js": {
"version": "git+https://git@github.com/uNetworking/uWebSockets.js.git#4558ee00f9f1f686fffe1accbfc2e85b1af9c50f",
"version": "git+https://git@github.com/uNetworking/uWebSockets.js.git#d39d4181daf5b670d44cbc1b18f8c28c85fd4142",
"dev": true,
"from": "uWebSockets.js@github:uNetworking/uWebSockets.js#v20.0.0"
"from": "uWebSockets.js@github:uNetworking/uWebSockets.js#v20.30.0"
},
"v8-compile-cache-lib": {
"version": "3.0.1",

View File

@@ -1,6 +1,6 @@
{
"name": "socket.io",
"version": "4.6.2",
"version": "4.7.0",
"description": "node.js realtime framework server",
"keywords": [
"realtime",
@@ -48,8 +48,9 @@
"dependencies": {
"accepts": "~1.3.4",
"base64id": "~2.0.0",
"cors": "~2.8.5",
"debug": "~4.3.2",
"engine.io": "~6.4.2",
"engine.io": "~6.5.0",
"socket.io-adapter": "~2.5.2",
"socket.io-parser": "~4.2.4"
},
@@ -60,14 +61,14 @@
"nyc": "^15.1.0",
"prettier": "^2.3.2",
"rimraf": "^3.0.2",
"socket.io-client": "4.6.2",
"socket.io-client": "4.7.0",
"socket.io-client-v2": "npm:socket.io-client@^2.4.0",
"superagent": "^8.0.0",
"supertest": "^6.1.6",
"ts-node": "^10.2.1",
"tsd": "^0.21.0",
"typescript": "^4.4.2",
"uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.0.0"
"uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.30.0"
},
"contributors": [
{

View File

@@ -70,6 +70,27 @@ describe("server attachment", () => {
});
});
it("should serve client with necessary CORS headers", (done) => {
const srv = createServer();
new Server(srv, {
cors: {
origin: "https://good-origin.com",
},
});
request(srv)
.get("/socket.io/socket.io.js")
.set("origin", "https://good-origin.com")
.buffer(true)
.end((err, res) => {
if (err) return done(err);
expect(res.headers["access-control-allow-origin"]).to.be(
"https://good-origin.com"
);
expect(res.status).to.be(200);
done();
});
});
it(
"should serve bundle with msgpack parser",
testSource("socket.io.msgpack.min.js")

View File

@@ -852,10 +852,6 @@ describe("socket", () => {
it("should not crash when messing with Object prototype (and other globals)", (done) => {
// @ts-ignore
Object.prototype.foo = "bar";
// @ts-ignore
global.File = "";
// @ts-ignore
global.Blob = [];
const io = new Server(0);
const socket = createClient(io);