- 6.5.0 (Jun 2023)
- 6.4.2 (May 2023)
- 6.4.1 (Feb 2023)
- 6.4.0 (Feb 2023)
- 6.3.1 (Jan 2023)
- 6.3.0 (Jan 2023)
- 3.6.1 (Nov 2022) (from the 3.x branch)
- 6.2.1 (Nov 2022)
- 3.6.0 (Jun 2022) (from the 3.x branch)
- 6.2.0 (Apr 2022)
- 6.1.3 (Feb 2022)
- 6.1.2 (Jan 2022)
- 6.1.1 (Jan 2022)
- 6.1.0 (Nov 2021)
- 6.0.1 (Nov 2021)
- 6.0.0 (Oct 2021)
- 5.2.0 (Aug 2021)
- 5.1.1 (May 2021)
- 5.1.0 (May 2021)
- 5.0.0 (Mar 2021)
- 4.1.1 (Feb 2021)
- 4.1.0 (Jan 2021)
- 4.0.6 (Jan 2021)
- 3.5.0 (Dec 2020) (from the 3.x branch)
- 4.0.5 (Dec 2020)
- 4.0.4 (Nov 2020)
- 4.0.3 (Nov 2020)
- 4.0.2 (Nov 2020)
- 4.0.1 (Oct 2020)
- 4.0.0 (Sep 2020)
- 3.4.2 (Jun 2020)
- 3.4.1 (Apr 2020)
6.5.0 (2023-06-16)
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, you can use the @fails-components/webtransport
package:
import { readFileSync } from "fs";
import { createServer } from "https";
import { Server } from "engine.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 engine = new Server({
transports: ["polling", "websocket", "webtransport"] // WebTransport is not enabled by default
});
engine.attach(httpsServer);
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;
}
engine.onWebTransportSession(value);
}
})();
h3Server.startServer();
Added in 123b68c.
Huge thanks to @OxleyS for helping!
ws@~8.11.0
(no change)
6.4.2 (2023-05-02)
A malicious client could send a specially crafted HTTP request, triggering an uncaught exception and killing the Node.js process:
TypeError: Cannot read properties of undefined (reading 'handlesUpgrades')
at Server.onWebSocket (build/server.js:515:67)
Please upgrade as soon as possible.
- include error handling for Express middlewares (#674) (9395782)
- prevent crash when provided with an invalid query param (fc480b4)
- typings: make clientsCount public (#675) (bd6d471)
- uws: prevent crash when using with middlewares (8b22162)
Huge thanks to @tyilo and @cieldeville for helping!
ws@~8.11.0
(no change)
6.4.1 (2023-02-20)
This release contains 6e78489, which exports the BaseServer
class in order to restore the compatibility with the nodenext
module resolution strategy of TypeScript.
Reference: https://www.typescriptlang.org/tsconfig/#moduleResolution
Related: socketio/socket.io#4621
ws@~8.11.0
(no change)
6.4.0 (2023-02-06)
- add support for Express middlewares (24786e7)
This commit implements middlewares at the Engine.IO level, because Socket.IO middlewares are meant for namespace authorization and are not executed during a classic HTTP request/response cycle.
A workaround was possible by using the allowRequest option and the "headers" event, but this feels way cleaner and works with upgrade requests too.
Syntax:
engine.use((req, res, next) => {
// do something
next();
});
// with express-session
import session from "express-session";
engine.use(session({
secret: "keyboard cat",
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}));
// with helmet
import helmet from "helmet";
engine.use(helmet());
ws@~8.11.0
(no change)
6.3.1 (2023-01-12)
ws@~8.11.0
(no change)
6.3.0 (2023-01-10)
- fix the ES module wrapper (ed87609)
- wait for all packets to be sent before closing the WebSocket connection (a65a047)
The trailing slash which was added by default can now be disabled:
import { Server } from "engine.io";
const server = new Server();
server.attach(httpServer, {
addTrailingSlash: false
});
In the example above, the clients can omit the trailing slash and use /engine.io
instead of /engine.io/
.
- add the wsPreEncodedFrame option (5e34722)
This will be used when broadcasting packets at the Socket.IO level.
See also: https://github.com/socketio/socket.io-adapter/commit/5f7b47d40f9daabe4e3c321eda620bbadfe5ce96
3.6.1 (2022-11-20)
A malicious client could send a specially crafted HTTP request, triggering an uncaught exception and killing the Node.js process:
Error: read ECONNRESET
at TCP.onStreamRead (internal/stream_base_commons.js:209:20)
Emitted 'error' event on Socket instance at:
at emitErrorNT (internal/streams/destroy.js:106:8)
at emitErrorCloseNT (internal/streams/destroy.js:74:3)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
errno: -104,
code: 'ECONNRESET',
syscall: 'read'
}
Please upgrade as soon as possible.
- catch errors when destroying invalid upgrades (83c4071)
ws@~7.4.2
(no change)
6.2.1 (2022-11-20)
A malicious client could send a specially crafted HTTP request, triggering an uncaught exception and killing the Node.js process:
Error: read ECONNRESET
at TCP.onStreamRead (internal/stream_base_commons.js:209:20)
Emitted 'error' event on Socket instance at:
at emitErrorNT (internal/streams/destroy.js:106:8)
at emitErrorCloseNT (internal/streams/destroy.js:74:3)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
errno: -104,
code: 'ECONNRESET',
syscall: 'read'
}
Please upgrade as soon as possible.
ws@~8.2.3
(no change)
3.6.0 (2022-06-06)
- add extension in the package.json main entry (#608) (3ad0567)
- do not reset the ping timer after upgrade (1f5d469), closes /github.com/socketio/socket.io-client-swift/pull/1309#issuecomment-768475704
- decrease the default value of maxHttpBufferSize (58e274c)
This change reduces the default value from 100 mb to a more sane 1 mb.
This helps protect the server against denial of service attacks by malicious clients sending huge amounts of data.
See also: https://github.com/advisories/GHSA-j4f2-536g-r55m
- increase the default value of pingTimeout (f55a79a)
6.2.0 (2022-04-17)
- add the "maxPayload" field in the handshake details (088dcb4)
So that clients in HTTP long-polling can decide how many packets they have to send to stay under the maxHttpBufferSize value.
This is a backward compatible change which should not mandate a new major revision of the protocol (we stay in v4), as we only add a field in the JSON-encoded handshake data:
0{"sid":"lv_VI97HAXpY6yYWAAAC","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":5000,"maxPayload":1000000}
6.1.3 (2022-02-23)
- typings: allow CorsOptionsDelegate as cors options (#641) (a463d26)
- uws: properly handle chunked content (#642) (3367440)
6.1.2 (2022-01-18)
- uws: expose additional uWebSockets.js options (#634) (49bb7cf)
- uws: fix HTTP long-polling with CORS (45112a3)
- uws: handle invalid websocket upgrades (8b4d6a8)
6.1.1 (2022-01-11)
A malicious client could send a specially crafted HTTP request, triggering an uncaught exception and killing the Node.js process:
RangeError: Invalid WebSocket frame: RSV2 and RSV3 must be clear at Receiver.getInfo (/.../node_modules/ws/lib/receiver.js:176:14) at Receiver.startLoop (/.../node_modules/ws/lib/receiver.js:136:22) at Receiver._write (/.../node_modules/ws/lib/receiver.js:83:10) at writeOrBuffer (internal/streams/writable.js:358:12)
This bug was introduced by this commit, included in [email protected]
, so previous releases are not impacted.
Thanks to Marcus Wejderot from Mevisio for the responsible disclosure.
- properly handle invalid data sent by a malicious websocket client (c0e194d)
6.1.0 (2021-11-08)
- fix payload encoding for v3 clients (ed50fc3)
- add an implementation based on uWebSockets.js (271e2df)
6.0.1 (2021-11-06)
- fix payload encoding for v3 clients (3f42262)
6.0.0 (2021-10-08)
The codebase was migrated to TypeScript (c0d6eaa)
An ES module wrapper was also added (401f4b6).
Please note that the communication protocol was not updated, so a v5 client will be able to reach a v6 server (and vice-versa).
Reference: https://github.com/socketio/engine.io-protocol
- the default export was removed, so the following code won't work anymore:
const eioServer = require("engine.io")(httpServer);
Please use this instead:
const { Server } = require("engine.io");
const eioServer = new Server(httpServer);
ws
version: ~8.2.3
(bumped from ~7.4.2
)
5.2.0 (2021-08-29)
No change on the server-side, this matches the client release.
5.1.1 (2021-05-16)
- properly close the websocket connection upon handshake error (4360686)
5.1.0 (2021-05-04)
- websocket: add a "wsPreEncoded" writing option (7706b12)
- websocket: fix write back-pressure (#618) (ad5306a)
5.0.0 (2021-03-10)
- increase the default value of pingTimeout (5a7fa13)
- remove dynamic require() with wsEngine (edb7343)
- the syntax of the "wsEngine" option is updated
Before:
const eioServer = require("engine.io")(httpServer, {
wsEngine: "eiows"
});
After:
const eioServer = require("engine.io")(httpServer, {
wsEngine: require("eiows").Server
});
4.1.1 (2021-02-02)
- do not reset the ping timer after upgrade (ff2b8ab), closes /github.com/socketio/socket.io-client-swift/pull/1309#issuecomment-768475704
4.1.0 (2021-01-14)
- add support for v3.x clients (663d326)
4.0.6 (2021-01-04)
3.5.0 (2020-12-30)
- add support for all cookie options (19cc582), closes /github.com/jshttp/cookie#options-1
- disable perMessageDeflate by default (5ad2736)
4.0.5 (2020-12-07)
No change on the server-side, this matches the client release.
4.0.4 (2020-11-17)
No change on the server-side, this matches the client release.
4.0.3 (2020-11-17)
No change on the server-side, this matches the client release.
4.0.2 (2020-11-09)
4.0.1 (2020-10-21)
- do not overwrite CORS headers upon error (fe093ba)
4.0.0 (2020-09-10)
More details about this release in the blog post: https://socket.io/blog/engine-io-4-release/
- ignore errors when forcefully closing the socket (#601) (dcdbccb)
- remove implicit require of uws (82cdca2)
- disable perMessageDeflate by default (078527a)
- Diff: v4.0.0-alpha.1...4.0.0
- Full diff: 3.4.0...4.0.0
- Client release: 4.0.0
- ws version: ^7.1.2
3.4.2 (2020-06-04)
- remove explicit require of uws (85e544a)
- Diff: 3.4.1...3.4.2
- Client release: -
- ws version: ^7.1.2
3.4.1 (2020-04-17)
- Diff: 3.4.0...3.4.1
- Client release: 3.4.1
- ws version: ^7.1.2
4.0.0-alpha.1 (2020-02-12)
- Diff: v4.0.0-alpha.0...v4.0.0-alpha.1
- Client release: v4.0.0-alpha.1
- ws version: ^7.1.2
4.0.0-alpha.0 (2020-02-12)
- decrease the default value of maxHttpBufferSize (734f9d1)
- disable cookie by default and add sameSite attribute (a374471), closes /github.com/jshttp/cookie#options-1
- generateId method can now return a Promise (f3c291f)
- reverse the ping-pong mechanism (31ff875)
- use the cors module to handle cross-origin requests (61b9492)
- the handlePreflightRequest option is removed by the change.
Before:
new Server({
handlePreflightRequest: (req, res) => {
res.writeHead(200, {
"Access-Control-Allow-Origin": 'https://example.com',
"Access-Control-Allow-Methods": 'GET',
"Access-Control-Allow-Headers": 'Authorization',
"Access-Control-Allow-Credentials": true
});
res.end();
}
})
After:
new Server({
cors: {
origin: "https://example.com",
methods: ["GET"],
allowedHeaders: ["Authorization"],
credentials: true
}
})
- the syntax has changed from
new Server({
cookieName: "test",
cookieHttpOnly: false,
cookiePath: "/custom"
})
to
new Server({
cookie: {
name: "test",
httpOnly: false,
path: "/custom"
}
})
All other options (domain, maxAge, sameSite, ...) are now supported.
- v3.x clients will not be able to connect anymore (they will send a ping packet and timeout while waiting for a pong packet).
- Diff: 3.4.0...v4.0.0-alpha.0
- Client release: v4.0.0-alpha.0
- ws version: ^7.1.2