The meaning is not modified: this packet type is still used by the
server when the connection to a namespace is refused. But I feel the
name makes more sense:
```js
socket.on("connect", () => {});
socket.on("connect_error", () => {});
// instead of
socket.on("error", () => {});
```
The binary detection was moved from the parser to the client/server in
[1], in order to allow the user to skip the binary detection for huge
JSON payloads.
```js
socket.binary(false).emit(...);
```
The binary detection is needed in the default parser, because the
payload is encoded with JSON.stringify(), which does not support binary
content (ArrayBuffer, Blob, ...).
But other parsers (like [2] or [3]) do not need this check, so we'll
move the binary detection back here and remove the socket.binary()
method, as this use case is now covered by the ability to provide your
own parser.
Note: the hasBinary method was copied from [4].
[1]: f44256c523
[2]: https://github.com/darrachequesne/socket.io-msgpack-parser
[3]: https://github.com/darrachequesne/socket.io-json-parser
[4]: https://github.com/darrachequesne/has-binary
This was needed in a previous version of the parser, which used msgpack
to encode the payload.
Blobs (and Files) will now be included in the array of binary
attachments without any additional transformation.
Breaking change: the encode method is now synchronous
See also 299849b002
The assertions were not checked, because the functions are asynchronous.
Besides, the Blob tests were throwing in the browser:
> Uncaught ReferenceError: can't access lexical declaration 'BlobBuilder' before initialization
It does not make sense to catch the errors thrown by JSON.stringify()
and convert them to an ERROR packet (which are meant for namespace
authentication errors), it should be caught higher in the stack.
Related: 92c530da47
An invalid packet was previously parsed as an ERROR packet, which was
then ignored because it didn't contain any 'nsp' (namespace) field.
This behavior was wrong because:
- it means the other side is sending invalid payloads, so the
connection must be closed right away
- ERROR packets are meant for namespace authentication failures
Parsing an invalid payload will now throw an error, which must be
caught by the caller.
Closes https://github.com/socketio/socket.io-parser/issues/86
When maxHttpBufferSize is large (1e8 bytes), a payload of length 100MB
can be sent like so:
99999991:422222222222222222222222222222222222222222222...
This massive packet can cause OOM via building up many many
`ConsOneByteString` objects due to concatenation:
99999989 `ConsOneByteString`s and then converting the massive integer to
a `Number`.
The performance can be improved to avoid this by using `substring`
rather than building the string via concatenation.
Below I tried one payload of length 7e7 as the 1e8 payload took so
long to process that it timed out before running out of memory.
```
==== JS stack trace =========================================
0: ExitFrame [pc: 0x13c5b79]
Security context: 0x152fe7b808d1 <JSObject>
1: decodeString [0x2dd385fb5d1] [/node_modules/socket.io-parser/index.js:~276] [pc=0xf59746881be](this=0x175d34c42b69 <JSGlobal Object>,0x14eccff10fe1 <Very long string[69999990]>)
2: add [0x31fc2693da29] [/node_modules/socket.io-parser/index.js:242] [bytecode=0xa7ed6554889 offset=11](this=0x0a2881be5069 <Decoder map = 0x3ceaa8bf48c9>,0x14eccff10fe1 <Very...
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
1: 0xa09830 node::Abort() [node]
2: 0xa09c55 node::OnFatalError(char const*, char const*) [node]
3: 0xb7d71e v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
4: 0xb7da99 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
5: 0xd2a1f5 [node]
6: 0xd2a886 v8::internal::Heap::RecomputeLimits(v8::internal::GarbageCollector) [node]
7: 0xd37105 v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [node]
8: 0xd37fb5 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]
9: 0xd3965f v8::internal::Heap::HandleGCRequest() [node]
10: 0xce8395 v8::internal::StackGuard::HandleInterrupts() [node]
11: 0x1042cb6 v8::internal::Runtime_StackGuard(int, unsigned long*, v8::internal::Isolate*) [node]
12: 0x13c5b79 [node]
```