Commit Graph

381 Commits

Author SHA1 Message Date
Damien Arrachequesne
7096e98a02 feat: add a "connection_error" event
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
2021-04-30 13:04:28 +02:00
Damien Arrachequesne
edb734316f feat: remove dynamic require() with wsEngine
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
2021-03-09 08:30:05 +01:00
Simone Mazzoni
868d89111d fix: set default protocol version to 3 (#616)
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
2021-03-09 08:23:36 +01:00
Damien Arrachequesne
5a7fa132c4 feat: increase the default value of pingTimeout
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
2021-03-02 08:49:58 +01:00
Damien Arrachequesne
ff2b8aba48 fix: do not reset the ping timer after upgrade
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
2021-02-02 10:48:02 +01:00
Damien Arrachequesne
663d326d18 feat: add support for v3.x clients
In order to ease the migration to Socket.IO v3, the Engine.IO server
can now communicate with v3.x clients.

```js
const eioServer = require("engine.io")(httpServer, {
  allowEIO3: true // false by default
});
```

If `allowEIO3` is false, the v3.x clients will now receive an HTTP 400
response ("Unsupported protocol version").

Note: the code of the v3 parser has been imported from [1] and
browser-related dependencies were removed.

[1]: https://github.com/socketio/engine.io-parser/tree/2.2.1

Related:

- https://github.com/socketio/engine.io-protocol/issues/35
- https://github.com/socketio/socket.io-protocol/issues/21
2021-01-14 01:44:52 +01:00
Marko Žarković
cec27502f5 fix: correctly pass the options when using the Server constructor (#610)
Fixes https://github.com/socketio/engine.io/issues/580
2020-12-30 10:04:47 +01:00
Damien Arrachequesne
c099338e04 refactor: remove binary handling for the polling transport
Since Engine.IO v4, the binary payloads are always encoded as base64
with the polling transport.

See https://github.com/socketio/engine.io-protocol#difference-between-v3-and-v4
2020-10-22 00:12:05 +02:00
Damien Arrachequesne
fe093bae1a fix: do not overwrite CORS headers upon error
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
2020-10-22 00:11:06 +02:00
Damien Arrachequesne
078527a384 feat: disable perMessageDeflate by default
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.
2020-09-10 15:46:04 +02:00
Damien Arrachequesne
ed29e5955d chore: bump engine.io-parser version
See also: https://github.com/socketio/engine.io-protocol#difference-between-v3-and-v4

Release: https://github.com/socketio/engine.io-parser/releases/tag/4.0.0
Diff: https://github.com/socketio/engine.io-parser/compare/2.2.0...4.0.0
2020-09-09 00:00:25 +02:00
Damien Arrachequesne
82cdca23ba fix: remove implicit require of uws
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
2020-06-04 14:24:42 +02:00
Damien Arrachequesne
dcdbccb3dd fix: ignore errors when forcefully closing the socket (#601)
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
2020-04-15 11:42:31 +02:00
Damien Arrachequesne
734f9d1268 feat: decrease the default value of maxHttpBufferSize
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.
2020-02-11 07:59:13 +01:00
Damien Arrachequesne
61b949259e feat: use the cors module to handle cross-origin requests
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
  }
})
```
2020-02-11 07:54:25 +01:00
Damien Arrachequesne
bafe684a19 refactor: refactor the handling of the options 2020-02-10 12:07:41 +01:00
Damien Arrachequesne
a374471d06 feat: disable cookie by default and add sameSite attribute
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
2020-02-05 08:33:00 +01:00
Damien Arrachequesne
31ff87593f feat: reverse the ping-pong mechanism
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
2020-02-04 12:31:44 +01:00
Damien Arrachequesne
f3c291fa61 feat: generateId method can now return a Promise
Related:

- https://github.com/socketio/engine.io/issues/538
- https://github.com/socketio/engine.io/pull/535
2020-01-14 21:58:42 +01:00
Damien Arrachequesne
33564b2391 refactor: use prettier to format code 2020-01-14 21:58:38 +01:00
Damien Arrachequesne
da93fb6ef3 refactor: migrate to ES6 syntax 2020-01-12 22:47:18 +01:00
Brian Kopp
c144895133 [feat] add additional debug messages (#586)
These additional messages will help more quickly diagnose the reason for error messages.
2019-09-13 11:21:37 +02:00
Damien Arrachequesne
ec4e12a063 [revert] Allow configuration of Access-Control-Allow-Origin value (#511)
This reverts commit ebf1a96f42.

Related: https://github.com/socketio/socket.io/issues/3381
2018-11-29 22:49:34 +01:00
Oliver Salzburg
9956445251 [fix] Replace deprecated Buffer usage (#565)
The `Buffer` constructor has been deprecated in favor of safer alternatives.
See https://nodejs.org/en/docs/guides/buffer-constructor-deprecation/
2018-11-19 22:22:13 +01:00
Jacco Flenter
ebf1a96f42 [feat] Allow configuration of Access-Control-Allow-Origin value (#511)
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
2018-11-02 07:38:16 +01:00
shapel
bc7b2393de [fix] Processing error code on abort connection (#562)
Fixes #561
2018-11-02 07:25:53 +01:00
Damien Arrachequesne
c6247514e2 [revert] Make generateId method async (#535)
That is a breaking change, which mandates a major bump.
2018-02-27 22:03:49 +01:00
Damien Arrachequesne
be3833bddd [refactor] Use Buffer.concat([]) to construct an empty buffer (#555) 2018-02-27 22:03:31 +01:00
Damien Arrachequesne
65b1ad1b8a [chore] Update default values for pingTimeout (#551)
`pingTimeout` now defaults to 5 seconds instead of 60 seconds.
2018-02-27 22:03:16 +01:00
Damien Arrachequesne
b1fa020675 [chore] Revert to ws as default wsEngine (#550)
Related:
- https://github.com/socketio/socket.io/issues/2956
- https://github.com/socketio/socket.io/issues/3100

Fixes #536
Fixes #516
Fixes #474
2017-12-29 22:39:34 +01:00
Nick Tazelaar
73e579a501 [refactor] Add some checks to prevent usage of undefined properties (#540) 2017-11-22 22:04:54 +01:00
efkan
2abb217e26 [feat] Make generateId method async (#535)
That change will allow to retrieve the client id asynchronously, from a database for example.
2017-10-20 08:00:29 +02:00
Damien Arrachequesne
49362abcd0 [fix] Fix undefined remoteAddress when using uws (#533)
Fixes https://github.com/socketio/socket.io/issues/2982
2017-10-11 07:29:52 +02:00
Damien Arrachequesne
e0d720c7f7 [fix] Check whether 'Origin' header has invalid characters (#531)
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
2017-09-02 14:16:14 +02:00
Mark Bjerke
38d639a5d0 [fix] Use explicit require of wsEngine (#523)
Because WebPack does not support variables in require statements.

Closes #522
2017-09-02 14:12:26 +02:00
Damien Arrachequesne
fd20b91208 [test] Use npm scripts instead of gulp (#530) 2017-09-01 14:21:57 +02:00
Raúl Montes
7f63d38b2a [fix] Fix undeterministic error in polling buffer processing (#529)
Ensure all assignments for chunks are Buffer when they should, even when onData is supposed to not
be called again.
2017-09-01 13:03:48 +02:00
Harutyun Amirjanyan
3dcc2d5cbd [fix] Use workaround for setEncoding bug in node 0.10+ (#527)
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.
2017-08-31 22:49:18 +02:00
Damien Arrachequesne
e76e035873 [fix] Fix null payload when aborting connection (#503) 2017-04-28 13:46:50 +02:00
Damien Arrachequesne
81ef0bc939 [feat] Add an option to toggle handling of OPTIONS requests (#491)
By setting `handlePreflightRequest` to false, OPTIONS request are no
longer processed by engine.io. A function can also be provided.
2017-03-11 09:04:00 +01:00
Luigi Pinca
cdb487dbdc [fix] Initialize the WebSocket server in the Server constructor (#476) 2017-01-30 15:52:00 +01:00
Damien Arrachequesne
274efa120e [feature] Add an initialPacket option (#471) 2017-01-22 07:51:27 +01:00
Konstantin Zolotarev
a3496ed6eb [fix] Discard packets when socket is closed (#469) 2017-01-05 21:01:37 +01:00
Matt90o
57ec952ff7 [docs] Fix spelling mistake (#466)
Edited a minor spelling mistake. 'Comparesses' -> 'Compresses'
2017-01-04 06:39:47 +01:00
Damien Arrachequesne
f72f6f3fa6 [fix] allowRequest failures now return 403 Forbidden (#452) 2016-12-22 08:41:51 +01:00
Jérémy Lal
7e50871c41 [chore] Use uws as default wsEngine, and ws as fallback (#459) 2016-12-12 22:02:03 +01:00
Damien Arrachequesne
79955091f5 [fix] Add proper response when handleUpgrade fails (#458)
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.
2016-12-10 22:01:18 +01:00
Damien Arrachequesne
b5292c7826 [refactor] Remove deprecated code used for nodejs v0.8 (#456) 2016-12-08 01:01:10 +01:00
Gatsbill
01c6a12de5 [perf] websocket optimisation (#453) 2016-12-05 23:59:24 +01:00
Dominik Paľo
8450d03f06 [docs] Rename ServerRequest to IncomingMessage (#448)
`http.ServerRequest` did refer to the HTTP API of Nodejs prior to v0.10
2016-12-05 23:28:01 +01:00