Those events will be emitted before the response headers are written to
the socket:
- "initial_headers": on the first request of the connection
- "headers": on all requests (HTTP long-polling and WebSocket upgrade)
Syntax:
```js
server.on("initial_headers", (headers, req) => {
headers["test"] = "123";
headers["set-cookie"] = "mycookie=456";
});
server.on("headers", (headers, req) => {
headers["test"] = "789";
});
```
Related:
- https://github.com/socketio/engine.io/issues/557
- https://github.com/socketio/socket.io/issues/3630
The "connection_error" event will be emitted when one of the following
errors occurs:
- Transport unknown
- Session ID unknown
- Bad handshake method
- Bad request
- Forbidden
- Unsupported protocol version
Syntax:
```js
server.on("connection_error", (err) => {
console.log(err.req); // the request object
console.log(err.code); // the error code, for example 1
console.log(err.message); // the error message, for example "Session ID unknown"
console.log(err.context); // some additional error context
});
```
Related:
- https://github.com/socketio/socket.io/issues/3819
- https://github.com/socketio/engine.io/issues/576
This change is necessary to get rid of:
> Critical dependency: the request of a dependency is an expression
when bundling the server with webpack.
BREAKING CHANGE: the syntax of the "wsEngine" option is updated
Before:
```js
const eioServer = require("engine.io")(httpServer, {
wsEngine: "eiows"
});
```
After:
```js
const eioServer = require("engine.io")(httpServer, {
wsEngine: require("eiows").Server
});
```
Related: https://github.com/socketio/engine.io/issues/609
socket.io-client-swift libs version <=15.2.0, which uses protocol
version 3, do not explicitly add the EIO query parameter at transport
initialization. This omission leads the server to treat the client as
a client that supports the protocol version 4, previously set as
default, which is not correct for those versions of the client lib.
From socket.io-client-swift version v16.0.0 the EIO query parameter is
explicitly passed to specify the protocol version supported, but since
the allowEIO3 parameter aims to make the server compatible with
previous versions which in most of the cases are already used in
production and not easily upgradable, it makes more sense to default
the EIO version to 3 if not explicitly set by the client since the
newer client versions pass the EIO protocol version in query
parameters.
Related: https://github.com/socketio/socket.io/issues/3794
This value was updated from 60000 to 5000 in [1], included in
`engine.io@3.2.0` (Feb 2018).
The reasoning back then:
Some users experienced long delays between disconnection on the
server-side and on the client-side. The "disconnect" event would take a
long time to fire in the browser, probably due to a timer being
delayed. Hence the change.
That being said, the current value (5s) now causes unexpected
disconnections when a big payload is sent over a slow network, because
it prevents the ping-pong packets from being exchanged between the
client and the server. This can also happen when a synchronous task
blocks the server for more than 5 seconds.
The new value (20s) thus seems like a good balance between quick
disconnection detection and tolerance to various delays.
Note: pingInterval + pingTimeout is still below the threshold of React
Native, which complains if a timer is set with a delay of more than 1
minute.
[1]: 65b1ad1b8a
Related:
- https://github.com/socketio/socket.io/issues/2770
- https://github.com/socketio/socket.io/issues/2769
- https://github.com/socketio/socket.io/issues/3054
- https://github.com/socketio/socket.io/issues/3376
There was two issues with this behavior:
- v3 clients (with allowEIO3: true) were also receiving a "ping" after
a successful upgrade, which is incorrect (in v3, it's the client that
sends the "ping", and the server answers with a "pong")
- the ping timer is not reset after upgrade on the client-side, so an
upgrade which took longer than the `pingTimeout` duration could lead to
a "ping timeout" error on the client-side
I think the latter issue is present since the initial implementation.
Related: https://github.com/socketio/socket.io-client-swift/pull/1309#issuecomment-768475704
The Access-Control-Allow-xxx headers added by the cors middleware were
overwritten when sending an error response.
Those lines should have been removed in [1].
[1]: 61b949259e
Related: https://github.com/socketio/engine.io/issues/605
The WebSocket permessage-deflate extension, while useful is some cases,
adds some extra memory overhead for each WebSocket connection, and
results in huge memory usage in production deployments.
It will now be disabled by default.
So that bundlers like webpack do not try to include it in the build.
As a side-effect, any implementation which matches the API of the ws
module can now be used.
Before that change, you had to explicitly exclude uws:
```
// webpack.config.js
module.exports = {
// ...
externals: {
uws: 'uws'
}
};
```
Related: https://github.com/socketio/engine.io/issues/575
In order to catch the following errors:
```
events.js:288
throw er; // Unhandled 'error' event
^
Error: write EPIPE
at afterWriteDispatched (internal/stream_base_commons.js:154:25)
at writeGeneric (internal/stream_base_commons.js:145:3)
at Socket._writeGeneric (net.js:780:11)
at Socket._write (net.js:792:8)
at doWrite (_stream_writable.js:441:12)
at writeOrBuffer (_stream_writable.js:425:5)
at Socket.Writable.write (_stream_writable.js:316:11)
at abortConnection (<myproject>/node_modules/engine.io/lib/server.js:506:12)
at <myproject>/node_modules/engine.io/lib/server.js:353:7
at Server.verify (<myproject>/node_modules/engine.io/lib/server.js:158:14)
at Server.handleUpgrade (<myproject>/node_modules/engine.io/lib/server.js:351:8)
```
Closes https://github.com/socketio/engine.io/issues/596, https://github.com/socketio/engine.io/pull/598
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.
We'll now rely on the standard cors module (https://github.com/expressjs/cors),
instead of the custom implementation that is error-prone and not
really user-friendly.
Breaking change: 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 cookie might be used for sticky-session, but is not mandatory so it
makes sense to disable it by default.
The change also add a SameSite=Lax attribute by default.
Breaking change: 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.
Reference: https://github.com/jshttp/cookie#options-1
The ping packets will now be sent by the server, because the timers set
in the browsers are not reliable enough. We suspect that a lot of
timeout problems came from timers being delayed on the client-side.
Breaking change: v3.x clients will not be able to connect anymore (they
will send a ping packet and timeout while waiting for a pong packet).
Related: https://github.com/socketio/engine.io/issues/312
It's now possible to specify an origins value (default value is '*') when initialising the engine. This value will be returned as the Access-Control-Allow-Origin value.
Related: #449
Since the 'Origin' header is used as response header, a value with invalid characters would trigger
'The header content contains invalid characters' errors.
Closes#517
The server often crashes with 'TypeError: "list" argument must be an Array of Buffers' errors,
which is caused by a bug in new versions of node, where setEncoding call does not work for messages
that are already in the queue.
This pull request makes sure that concat is never called in the non binary case, even if
setEncoding does not work properly.
When the `verify` method fails, the current implementation closes the
connection immediately, which is understood by some proxy (such as
nginx) as if the server was not available (resulting in "upstream
prematurely closed connection while reading response header from
upstream" error). That commit make sure a proper response is sent
before closing the connection.