The yeast() method could generate the same string twice when used in
two different iframes, which can cause Safari to only send one HTTP
request (deduplication) and trigger an HTTP 400 error afterwards since
the two iframes share the same session ID.
This new method, combining 5 chars from the timestamp and 3 chars from
Math.random() should be sufficient for our use case.
Related: https://github.com/socketio/engine.io/issues/690
See also: 874484cc1e
The debug package was not included anymore in the dev bundle since the
migration from webpack to rollup ([1]) in version 6.0.0.
[1]: 27de300de4
See also: 4683a954d4
By default, Babel uses `Object.defineProperty()` when transpiling
classes. We'll now use the loose mode which creates a more terse
output.
| | before | after |
|----------|--------|--------|
| min+gzip | 8.8 KB | 8.6 KB |
| min+br | 8.0 KB | 7.7 KB |
Reference: https://babeljs.io/docs/babel-plugin-transform-classes
This commit adds the ability to provide a list of transport
implementations to use when connecting to an Engine.IO server.
This can be used to use HTTP long-polling based on `fetch()`, instead
of the default implementation based on the `XMLHttpRequest` object.
```
import { Socket, Fetch, WebSocket } from "engine.io-client";
const socket = new Socket({
transports: [Fetch, WebSocket]
});
```
This is useful in some environments that do not provide a
`XMLHttpRequest` object, like Chrome extension background scripts.
> XMLHttpRequest() can't be called from a service worker, extension or
otherwise. Replace calls from your background script to
XMLHttpRequest() with calls to global fetch().
Source: https://developer.chrome.com/docs/extensions/develop/migrate/to-service-workers#replace-xmlhttprequest
Related:
- https://github.com/socketio/engine.io-client/issues/716
- https://github.com/socketio/socket.io/issues/4980
This is also useful when running the client with Deno or Bun, as it
allows to use the built-in `fetch()` method and `WebSocket` object,
instead of using the `xmlhttprequest-ssl` and `ws` Node.js packages.
Related: https://github.com/socketio/socket.io-deno/issues/12
This feature also comes with the ability to exclude the code related to
unused transports (a.k.a. "tree-shaking"):
```js
import { SocketWithoutUpgrade, WebSocket } from "engine.io-client";
const socket = new SocketWithoutUpgrade({
transports: [WebSocket]
});
```
In that case, the code related to HTTP long-polling and WebTransport
will be excluded from the final bundle.
Related: https://github.com/socketio/socket.io/discussions/4393
When setting the `tryAllTransports` option to `true`, if the first
transport (usually, HTTP long-polling) fails, then the other transports
will be tested too.
This is useful in two cases:
> when HTTP long-polling is disabled on the server, or if CORS fails
Related:
- https://github.com/socketio/engine.io-client/issues/575
- https://github.com/socketio/socket.io-client/issues/1448
> when WebSocket is tested first (`transports: ["websocket", "polling"])
Related:
- https://github.com/socketio/engine.io-client/issues/714
- https://github.com/socketio/socket.io-client/issues/1599
The only potential downside is that the connection attempt could take
more time in case of failure, as there have been reports of WebSocket
connection errors taking several seconds before being detected (that's
one reason for using HTTP long-polling first). That's why the option
defaults to `false` for now.
The regular expression used to parse the URL provided by the user has a
time complexity of O(n^2), hence the length limitation.
Please note that this does not seem realistically exploitable, as an
attacker would have to be able to provide a malicious URL to the user
and inject it in the Engine.IO client.
We could also have:
- modified the regex, but there are a lot of edge cases and the current test coverage is probably not sufficient
- use the built-in URL object, but we would have to add a polyfill for old platforms like IE
Thanks to Young-jin Hwang from the Soonchunhyang University for the
responsible disclosure.
The Node.js client will now properly receive binary data as Buffers
instead of ArrayBuffers, when connecting with WebTransport. Browser
clients will still receive ArrayBuffers though (or Blobs, if
`socket.binaryType` is set to "blob").
WebTransport being a stream-based protocol, the chunking boundaries are
not necessarily preserved. That's why we need a header indicating the
type of the payload (plain text or binary) and its length.
See also: a306db09e8
This commit ensures that when there are multiple possible upgrades
(like WebSocket and WebTransport), then the WebTransport is favored and
the other upgrades are delayed.
Following 7195c0f305
When setting the `withCredentials` option to `true`, the Node.js client
will now include the cookies in the HTTP requests, making it easier to
use it with cookie-based sticky sessions.
Related: https://github.com/socketio/socket.io/issues/3812