Before this commit, after the initial handshake, an HTTP request with a "application/octet-stream"
content type would trigger a "invalid content" error at the Engine.IO level, but would not be
properly closed, which could possibly lead to resource exhaustion.
This behavior was introduced in [1] (engine.io@4.1.0, January 2021).
[1]: 663d326d18
Note: `npm ci` is always required because it's the npm cache that is cached, not the node_modules/ directory.
Reference: https://github.com/actions/setup-node
EventNamesWithAck previously excluded events whose callback had no
non-error arguments (e.g. `(cb: () => void) => void` or
`(cb: (err: Error) => void) => void`). This made it impossible to use
emitWithAck as a simple acknowledgement mechanism without data.
The fix removes the FirstNonErrorArg void check while keeping the guard
against events with no parameters at all, so events like `() => void`
(no callback) are still correctly excluded.
Related: https://github.com/socketio/socket.io/issues/5257
When a packet contains binary elements, the built-in parser does not modify them and simply sends them in their own WebSocket frame.
Example: `socket.emit("some event", Buffer.of(1,2,3))`
is encoded and transferred as:
- 1st frame: 51-["some event",{"_placeholder":true,"num":0}]
- 2nd frame: <buffer 01 02 03>
where:
- `5` is the type of the packet (binary message)
- `1` is the number of binary attachments
- `-` is the separator
- `["some event",{"_placeholder":true,"num":0}]` is the payload (including the placeholder)
On the receiving end, the parser reads the number of attachments and buffers them until they are all received.
Before this change, the built-in parser accepted any number of binary attachments, which could be exploited to make the server run out of memory.
The number of attachments is now limited to 10, which should be sufficient for most use cases.
The limit can be increased with a custom `parser`:
```js
import { Encoder, Decoder } from "socket.io-parser";
const io = new Server({
parser: {
Encoder,
Decoder: class extends Decoder {
constructor() {
super({
maxAttachments: 20
});
}
}
}
});
```
Remove the `return` in the catch block of ClusterAdapter.broadcast() so
that super.broadcast() is still called when remote publishing fails.
This ensures local sockets receive the event even if the cluster publish
errors out (e.g. due to a serialization error in the adapter layer).
Related: https://github.com/socketio/socket.io/issues/5456
Since engine.io@6.6.5, the generated .d.ts files import types from "ws"
(WebSocket, PerMessageDeflateOptions), but @types/ws was not declared as
a dependency. This causes TypeScript compilation errors for consumers
who do not have @types/ws installed.
This follows the existing pattern where @types/cors and @types/node are
already listed as dependencies.
Related: https://github.com/socketio/socket.io/issues/5437
The uServer (uWebSockets.js) implementation did not emit
"initial_headers" and "headers" events during WebSocket upgrades,
unlike the regular Server which does this via the ws "headers" event.
Related: https://github.com/socketio/socket.io/issues/5300
When using `emitWithAck` with a timeout, if clients didn't respond
and the timeout triggers, the ack callbacks remained in `socket.acks`
Map indefinitely, causing a memory leak.
Related: https://github.com/socketio/socket.io/issues/4984
We should eventually be able to replace:
- mocha and nyc with Node.js built-in test runner (`node:test`)
- expect.js with Node.js built-in assertion library (`node:assert`)
The "_placeholder" attribute is used when sending binary data, and was
incorrectly mangled (converted to a random short property, like "it",
to reduce the bundle size).
Related:
- ca9e994815
- https://github.com/socketio/socket.io/issues/5215
[skip ci]